From: Dave Hart Date: Sun, 20 Feb 2011 20:23:00 +0000 (+0000) Subject: Attempt typical subpackage approach for libevent X-Git-Tag: NTP_4_2_7P131~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=430735e4a6965365e863255d5a400b9676f68d04;p=thirdparty%2Fntp.git Attempt typical subpackage approach for libevent sntp test cleanup IPv6 hackery Split up ntp_lib.m4 into smaller, more specific subsets Use {step,adj}_systime from libntp. Use EX_* codes for exit status. libevent cleanup libevent upgrade Move blocking worker and intres from ntpd to libntp. Move AC_FUNC_FORK and AC_FUNC_ALLOCA to ntp_libntp.m4 along with move of intres/blocking worker to libntp. Use %m instead of strerror(). make -lz depend on zlib.h hp-ux portability fix portability Allow libevent's regress to be skipped in make check. Switch sntp from evdns to blocking worker intres. Quiet "signal_no_reset: signal 18 had flags 20000" on OpenSolaris, adding SA_NOCLDSTOP to IGNORED_SA_FLAGS. Be consistent about how blocking children go away: 1. Parent requests them to go by closing pipe or CHILD_EXIT_REQ. 2. Child goes away quietly. 3. Parent sees them gone via broken resp pipe or CHILD_GONE_RESP. 4. Parent clears blocking_children entry for reuse. Make delay between queries to addresses resolved from same hostname per-family in sntp, as ntpd won't consider our v4 and v6 source addresses to be one remote rate-limit target. use freeaddrinfo() in ntpq's getnetnum(). valgrind warned of branch dependent on uninitialized value, irig_decode()'s local syncdig. Free OpenSSL dynamic allocations atexit. Enable pthreads build libntp autoconf macro cleanup Move "can't write KoD file" warning from sntp shutdown to startup. Use libevent log callback to redirect messages from stderr to msyslog() enable libevent debug mode if sntp debug > 0 Issue a single read event for each socket, rather than one per query. Do not attempt to read in socket callback for EV_TIMEOUT. ipv6 fixes for sntp Crib some pthread m4 from BIND for libisc. Fix step/slew logic in sntp. sntp --headspace option (default 10ms) spaces queries. Provide less-broken gettimeofday_cached(). Add support for --(no-)wait and -uctimeout Remove duplicate clock_gettime/clock_settime logic from sntp/configure.ac, it's now in sntp/m4/ntp_libntp.m4. Bump config.cache version stamps to account for cache-incompatible change to librt detection. Omit unused code with recent gcc and gnu ld. AC_LANG update for openldap autoconf macros Clean up AC_DEFINE and AC_DEFINE_UNQUOTED arg quoting in openldap*.m4 add a timeout for test-eof.c as it may hang under HP-UX 10.20 Use pthreads for blocking worker rather than fork, if possible. Quiet alignment warning due to casting sockaddr * to sockaddr_u * Quiet ntp_control.c and ntp_request.c warnings about casting char * to u_int32 * using unions. Use void * rather than char * for variant pointers to help with pointer cast increases required alignment warnings. Fix many warnings enabled with -Wcast-align, when casting a pointer to a more-strictly-aligned underlying type. preset ol_with_yielding_select=${ol_with_yielding_select-auto} Also change tests to use x prefix as insurance against other issues. We always need the PTHREADS AM_CONDITIONAL. Use the OL check. Use NTP_LIBEVENT m4sh macro to decide between installed and tearoff libevent. Add readonly arg to kod_init_kod_db() for tests -- prevents editing test baseline input KoD files during make check, regression limited to sntp/libevent branch. Switch libevent-2.0.10-stable from ACX_PTHREADS to OL_THREAD_CHECK Use socketpair() instead of pipe() when available, as avoiding EV_FEATURE_FDS allows libevent to use a faster backend on systems like Linux without an O(1) backend that handles pipes. Remove contentious libevent-cfg sentinel files, modify libevent's confgure args via $ac_configure_args. Strip unneeded checks from ntp_ipv6.m4: for struct sockaddr_storage member ss_family for struct sockaddr_storage member ss_len for struct sockaddr_storage member __ss_len Move things used by libntp from top-level configure.ac to NTP_LIBNTP and NTP_IPV6 Change "forked worker child (pid 0)" from msyslog() to DPRINTF(). Change initial socket boundary message from DEBUG-only msyslog() to DPRINTF(). bk: 4d617824JKc83Vw-PzIWDhw2VggjWw --- diff --git a/ChangeLog b/ChangeLog index cb703a826..7a14fa48e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,22 @@ -* Import libevent. +* Convert sntp to libevent event-driven socket programming. Instead of + blocking name resolution and querying one NTP server at a time, + resolve server names and send NTP queries without blocking. Add + sntp command-line options to adjust timing and optionally wait for all + servers to respond instead of exiting after the first. +* Move "can't write KoD file" warning from sntp shutdown to startup. +* Import libevent 2.0.10-stable plus local patches as a tearoff, used + only if the target system lacks an installed libevent 2.0.9 or later. +* Move blocking worker and resolver to libntp from ntpd. +* Use threads rather than forked child processes for blocking worker + when possible. Override with configure --disable-thread-support. +* Move init_logging(), change_logfile(), and setup_logfile() from ntpd + to libntp, use them in sntp. +* Test --without-sntp in flock-build script's -no-refclocks variety. +* Avoid invoking config.status twice in a row in build script. +* Move more m4sh tests needed by libntp to shared .m4 files. +* Split up ntp_libntp.m4 into smaller, more specific subsets. +* Enable gcc -Wcast-align, fix many instances of warnings when casting + a pointer to a more-strictly-aligned underlying type. * [Bug 1786] Remove extra semicolon from ntp_proto.c . (4.2.7p120) 2011/01/20 Released by Harlan Stenn * Change new timeval and timespec to string routines to use snprintf() diff --git a/Makefile.am b/Makefile.am index 502f2db3f..dfe979382 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,11 +1,10 @@ ## LIBOPTS_CHECK_NOBUILD works with Automake 1.10 now AUTOMAKE_OPTIONS = foreign 1.10 -ACLOCAL_AMFLAGS = -I sntp/m4 -I sntp/libopts/m4 +ACLOCAL_AMFLAGS = -I sntp/m4 -I sntp/libopts/m4 -I sntp/libevent/m4 NULL = -SUBDIRS = -SUBDIRS += \ +SUBDIRS = \ scripts \ include \ ElectricFence \ @@ -25,26 +24,6 @@ SUBDIRS += \ tests \ $(NULL) -DIST_SUBDIRS = \ - scripts \ - include \ - ElectricFence \ - libntp \ - libparse \ - sntp \ - ntpd \ - ntpdate \ - ntpdc \ - ntpq \ - ntpsnmpd \ - parseutil \ - adjtimed \ - clockstuff \ - kernel \ - util \ - tests \ - $(NULL) - DISTCHECK_CONFIGURE_FLAGS = -C --with-sntp EXTRA_DIST = \ diff --git a/adjtimed/Makefile.am b/adjtimed/Makefile.am index 5f3c07c1a..da83917f3 100644 --- a/adjtimed/Makefile.am +++ b/adjtimed/Makefile.am @@ -12,14 +12,14 @@ EXTRA_PROGRAMS= adjtimed INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += $(LIBOPTS_CFLAGS) AM_CFLAGS = @CFLAGS_NTP@ AM_CPPFLAGS = @CPPFLAGS_NTP@ -LDADD= ../libntp/libntp.a +LDADD= ../libntp/libntp.a @LDADD_LIBNTP@ @PTHREAD_LIBS@ ETAGS_ARGS= Makefile.am check-libntp: FRC diff --git a/build b/build index 9f26752cf..6d4c76047 100755 --- a/build +++ b/build @@ -172,10 +172,11 @@ CONFIGURE="../configure --cache-file=../config.cache-$IAM$CCSUF $CONFIG_ARGS" ( "$TEST" config.status -nt ../configure && $TEST sntp/config.status -nt ../sntp/configure ) || "$NICEB" -7 $CONFIGURE - "$NICEB" -5 ./config.status && - ( cd sntp && "$NICEB" -5 ./config.status ) && - "$NICEB" -14 ${MAKE-make} && - "$NICEB" -11 ${MAKE-make} check + "$TEST" Makefile -nt config.status || + "$NICEB" -5 ./config.status + "$TEST" sntp/Makefile -nt sntp/config.status || + ( cd sntp && "$NICEB" -5 ./config.status ) + "$NICEB" -14 ${MAKE-make} && "$NICEB" -11 ${MAKE-make} check ) > $LOGF 2>&1 EXITCODE=$? diff --git a/clockstuff/Makefile.am b/clockstuff/Makefile.am index 3e912345e..96dca24a5 100644 --- a/clockstuff/Makefile.am +++ b/clockstuff/Makefile.am @@ -9,14 +9,14 @@ clktest_SOURCES = clktest.c clktest-opts.c clktest-opts.h INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += $(LIBOPTS_CFLAGS) AM_CFLAGS = @CFLAGS_NTP@ AM_CPPFLAGS = @CPPFLAGS_NTP@ -LDADD = ../libntp/libntp.a +LDADD = ../libntp/libntp.a @LDADD_LIBNTP@ @PTHREAD_LIBS@ propdelay_LDADD = $(LIBM) $(LDADD) run_ag= cd $(srcdir) && env PATH="$(abs_builddir):$(PATH)" \ diff --git a/configure.ac b/configure.ac index 9fc56bd8e..e4dd2d98c 100644 --- a/configure.ac +++ b/configure.ac @@ -26,7 +26,7 @@ AC_CONFIG_AUX_DIR([sntp/build-aux]) # the date YYYYMMDD optionally with -HHMM if there is more than one # bump in a day. -ntp_configure_cache_version=20100916 +ntp_configure_cache_version=20110219 # When the cache version of config.cache and configure do not # match, NTP_CACHEVERSION will flush the cache. @@ -54,20 +54,12 @@ ntp_parse_ok=${ntp_parse_ok=no} ntp_ripe_ncc_ok=${ntp_parse_ok=no} ntp_jupiter_ok=${ntp_jupiter_ok=no} -dnl must come before AC_PROG_CC or similar -AC_USE_SYSTEM_EXTENSIONS - -dnl we need to check for cross compile tools for vxWorks here -AC_PROG_CC -# Ralf Wildenhues: With per-target flags we need CC_C_O -# AM_PROG_CC_C_O supersets AC_PROG_CC_C_O -AM_PROG_CC_C_O AC_PROG_CPP AC_PROG_CXX AC_PROG_YACC NTP_LIBNTP -NTP_VPATH_HACK +NTP_VPATH_HACK dnl used only by ntpd/Makefile.am # So far, the only shared library we might use is libopts. # It's a small library - we might as well use a static version of it. @@ -90,9 +82,6 @@ case "${enable_libopts_install+set}" in esac LIBOPTS_CHECK_NOBUILD([sntp/libopts]) -AC_FUNC_FORK -AC_FUNC_ALLOCA - AC_MSG_CHECKING([for deprecated --with-arlib]) AC_ARG_WITH([arlib], AS_HELP_STRING([--with-arlib], [- deprecated, arlib not distributed]), @@ -109,15 +98,10 @@ dnl we need to check for cross compile tools for vxWorks here AC_PROG_AWK AC_PROG_MAKE_SET -rm -f conftest* - - AC_SUBST([CFLAGS]) AC_SUBST([LDFLAGS]) AC_PROG_LN_S -AC_PROG_GCC_TRADITIONAL -AC_C_VOLATILE AC_ISC_POSIX AC_PATH_PROG([PATH_PERL], [perl]) @@ -166,16 +150,8 @@ case "$host" in ;; esac -AC_PROG_INSTALL - -# Checks for libraries. -NTP_LINEEDITLIBS - -AC_SEARCH_LIBS([inet_pton], [nsl]) +# HMS: a check for -lnsl used to be here - now being done in NTP_LIBNTP AC_SEARCH_LIBS([openlog], [gen syslog]) -AC_SEARCH_LIBS([MD5Init], [md5 md]) -AC_CHECK_FUNCS([MD5Init]) - dnl Digital UNIX V4.0 and Solaris 7 have POSIX.1c functions in -lrt dnl Solaris 2.6 only has -lposix4; in Solaris 7, this is a symlink to -lrt, @@ -191,22 +167,12 @@ case "$host" in *-*-osf4*) ;; *-*-osf5*) ;; *) + # HMS: Make sure we check for -lrt for clock_* before this... AC_CHECK_LIB([rt], [sched_setscheduler], [], [AC_CHECK_LIB([posix4], [sched_setscheduler])]) ;; esac -case "$host" in - *-*-darwin*) - AC_SEARCH_LIBS([res_9_init], [resolv]) - ;; - *) AC_SEARCH_LIBS([res_init], [resolv]) - ;; -esac -AC_HEADER_RESOLV -AC_CHECK_FUNCS([res_init], , [AC_CHECK_FUNCS([__res_init])]) - -AC_HEADER_STDC AC_CHECK_HEADERS([bstring.h]) AC_CHECK_HEADER( [dns_sd.h], @@ -221,18 +187,8 @@ case "$ac_cv_lib_dns_sd_DNSServiceRegister" in yes) LIBS="-ldns_sd $LIBS" esac -AC_CHECK_HEADERS([errno.h fcntl.h ieeefp.h inttypes.h kvm.h math.h]) +AC_CHECK_HEADERS([fcntl.h ieeefp.h inttypes.h kvm.h math.h]) -AC_CHECK_HEADERS( - [md5.h], - [], - [], - [ - #ifdef HAVE_SYS_TYPES_H - # include - #endif - ] -) AC_CHECK_HEADERS([memory.h netdb.h poll.h]) AC_CHECK_HEADERS([sgtty.h stdlib.h string.h termio.h]) AC_CHECK_HEADERS([termios.h timepps.h timex.h unistd.h]) @@ -266,7 +222,6 @@ case "$host" in AC_CHECK_FUNCS([getpassphrase]) esac -AC_CHECK_HEADERS([arpa/nameser.h]) AC_CHECK_HEADERS([net/if6.h]) AC_CHECK_HEADERS([net/route.h], [], [], [ @@ -274,41 +229,6 @@ AC_CHECK_HEADERS([net/route.h], [], [], [ #include #include ]) -AC_CHECK_HEADERS([netinet/in_system.h netinet/in_systm.h netinet/in.h]) -AC_CHECK_HEADERS([net/if_var.h], [], [], [ - #if HAVE_SYS_TYPES_H - # include - #endif - #ifdef HAVE_SYS_SOCKET_H - # include - #endif - #ifdef HAVE_NETINET_IN_H - # include - #endif - #ifdef HAVE_NET_IF_H - # include - #endif -]) -AC_CHECK_HEADERS([netinet/ip.h netinet/in_var.h], [], [], [ - #ifdef HAVE_SYS_TYPES_H - # include - #endif - #ifdef HAVE_SYS_SOCKET_H - # include - #endif - #ifdef HAVE_NET_IF_H - # include - #endif - #ifdef HAVE_NETINET_IN_H - # include - #endif - #ifdef HAVE_NET_IF_VAR_H - # include - #endif - #ifdef HAVE_NETINET_IN_SYSTM_H - # include - #endif -]) # Check for IPTOS_PREC AC_CACHE_CHECK( @@ -353,9 +273,8 @@ case "$host" in ;; esac AC_CHECK_HEADERS([sys/ipc.h sys/lock.h sys/mman.h]) -AC_CHECK_HEADERS([sys/modem.h sys/param.h sys/ppsclock.h]) # HMS: Check sys/proc.h and sys/resource.h after some others -AC_CHECK_HEADERS([sys/ppstime.h sched.h]) +AC_CHECK_HEADERS([sys/modem.h sys/ppsclock.h sys/ppstime.h sched.h]) case "$ac_cv_header_sched_h" in yes) ;; @@ -378,43 +297,8 @@ case "$host" in AC_CHECK_HEADERS([machine/soundcard.h sys/soundcard.h]) ;; esac -AC_CHECK_HEADERS([sys/stat.h sys/stream.h stropts.h sys/stropts.h]) -# sys/sysctl.h depends on sys/param.h on OpenBSD - Bug 1576 -AC_CHECK_HEADERS([sys/sysctl.h], [], [], -[#if defined HAVE_SYS_PARAM_H -# include -#endif]) -AC_CHECK_HEADERS([sys/syssgi.h sys/systune.h]) -AC_CHECK_HEADERS([sys/termios.h sys/time.h sys/signal.h]) -AC_EGREP_CPP( - [yes], - [ - #ifdef HAVE_SYS_TIME_H - # include - #endif - #ifdef HAVE_ERRNO_H - # include - #endif - #include - #ifdef PPS_API_VERS_1 - yes - #endif - ], - [AC_CHECK_HEADERS( - [sys/timepps.h], - [], - [], - [ - #ifdef HAVE_SYS_TIME_H - # include - #endif - #ifdef HAVE_ERRNO_H - # include - #endif - ] - )] -) -AC_CHECK_HEADERS([sys/timers.h sys/tpro.h sys/types.h sys/wait.h]) +AC_CHECK_HEADERS([sys/stat.h sys/stream.h stropts.h sys/stropts.h sys/syssgi.h]) +AC_CHECK_HEADERS([sys/systune.h sys/termios.h sys/tpro.h sys/wait.h]) case "$host" in *-convex-*) AC_CHECK_HEADERS([/sys/sync/queue.h /sys/sync/sema.h]) @@ -498,114 +382,9 @@ AC_CHECK_HEADERS([sys/timex.h], [], [], [ #endif ]) -AC_CHECK_HEADERS([resolv.h], [], [], [ - #ifdef HAVE_SYS_TYPES_H - # include - #endif - #ifdef HAVE_NETINET_IN_H - # include - #endif - #ifdef HAVE_ARPA_NAMESER_H - # include - #endif -]) - -AC_CACHE_CHECK( - [for basic volatile support], - [ntp_cv_c_volatile], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - ]], - [[ - volatile int x; - ]] - )] - [ntp_cv_c_volatile=yes], - [ntp_cv_c_volatile=no] - )] -) -case "$ntp_cv_c_volatile" in - yes) - ;; - *) - AC_DEFINE([volatile], [], [define away volatile?]) - ;; -esac - -AC_C_BIGENDIAN AC_TYPE_SIGNAL AC_TYPE_OFF_T -AC_TYPE_SIZE_T -AC_CHECK_TYPES([long, uintptr_t]) - -AH_VERBATIM([TYPEDEF_UINTPTR_T], -[/* Provide a typedef for uintptr_t? */ -#ifndef HAVE_UINTPTR_T -typedef unsigned int uintptr_t; -#define HAVE_UINTPTR_T 1 -#endif]) - -AC_CHECK_TYPES([time_t, int32, u_int32]) - -case "$ac_cv_type_int32::$ac_cv_header_resolv_h" in - no::yes) - AC_CACHE_CHECK( - [for int32 with DNS headers included], - [ntp_cv_type_int32_with_dns], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #ifdef HAVE_ARPA_NAMESER_H - # include - #endif - #include - ]], - [[ - size_t cb = sizeof(int32); - ]] - )], - [ntp_cv_type_int32_with_dns=yes], - [ntp_cv_type_int32_with_dns=no] - )] - ) - case "$ntp_cv_type_int32_with_dns" in - yes) - AC_DEFINE([HAVE_INT32_ONLY_WITH_DNS], [1], - [int32 type in DNS headers, not others.]) - esac -esac - -case "$ac_cv_type_u_int32::$ac_cv_header_resolv_h" in - no::yes) - AC_CACHE_CHECK( - [for u_int32 with DNS headers included], - [ntp_cv_type_u_int32_with_dns], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #ifdef HAVE_ARPA_NAMESER_H - # include - #endif - #include - ]], - [[ - size_t cb = sizeof(u_int32); - ]] - )], - [ntp_cv_type_u_int32_with_dns=yes], - [ntp_cv_type_u_int32_with_dns=no] - )] - ) - case "$ntp_cv_type_u_int32_with_dns" in - yes) - AC_DEFINE([HAVE_U_INT32_ONLY_WITH_DNS], [1], - [u_int32 type in DNS headers, not others.]) - esac -esac - -AC_CHECK_SIZEOF([time_t]) -AC_STRUCT_TM +AC_STRUCT_TM dnl defines TM_IN_SYS_TIME used by refclock_parse.c AC_CACHE_CHECK( [for a fallback value for HZ], @@ -857,95 +636,39 @@ case "$ntp_cv_struct_clockinfo_has_hz" in AC_DEFINE([HAVE_TICKADJ_IN_STRUCT_CLOCKINFO], [1], [Obvious]) esac -AC_CACHE_CHECK( - [for struct timespec], - [ntp_cv_struct_timespec], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #include - /* Under SunOS, timespec is in sys/timepps.h, - which needs errno.h and FRAC */ - #ifdef HAVE_ERRNO_H - # include - #endif - #ifdef HAVE_SYS_TIMEPPS_H - # define FRAC 4294967296 - # include - #endif - ]], - [[ - struct timespec n; - ]] - )], - [ntp_cv_struct_timespec=yes], - [ntp_cv_struct_timespec=no] - )] -) -case "$ntp_cv_struct_timespec" in - yes) - AC_DEFINE([HAVE_STRUCT_TIMESPEC], [1], [struct timespec declared?]) -esac - -AC_CACHE_CHECK( - [for struct ntptimeval], - [ntp_cv_struct_ntptimeval], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #include - #include - ]], - [[ - struct ntptimeval n; - ]] - )], - [ntp_cv_struct_ntptimeval=yes], - [ntp_cv_struct_ntptimeval=no] - )] -) case "$ntp_cv_struct_ntptimeval" in yes) - AC_DEFINE([HAVE_STRUCT_NTPTIMEVAL], [1], - [Do we have struct ntptimeval?]) + AC_CHECK_MEMBERS( + [struct ntptimeval.time.tv_nsec], + [], + [], + [ + #ifdef HAVE_SYS_TIME_H + # include + #else + # ifdef HAVE_TIME_H + # include + # endif + #endif + #ifdef HAVE_SYS_TIMEX_H + # include + #else + # ifdef HAVE_TIMEX_H + # include + # endif + #endif + ] + ) esac -AC_CHECK_MEMBERS( - [struct ntptimeval.time.tv_nsec], - [], - [], - [ - #ifdef HAVE_SYS_TIME_H - #include - #else - # ifdef HAVE_TIME_H - # include - # endif - #endif - #ifdef HAVE_SYS_TIMEX_H - # include - #else - # ifdef HAVE_TIMEX_H - # include - # endif - #endif - ] -) +#### -case "$host" in - *-*-aix[[456]]*) - # (prr) aix 4.1 doesn't have clock_settime, but in aix 4.3 it's a stub - # (returning ENOSYS). I didn't check 4.2. If, in the future, - # IBM pulls its thumbs out long enough to implement clock_settime, - # this conditional will need to change. Maybe use AC_TRY_RUN - # instead to try to set the time to itself and check errno. - ;; - *) - AC_SEARCH_LIBS([clock_gettime], [rt]) - AC_CHECK_FUNCS([clock_gettime clock_settime]) - ;; -esac +saved_LIBS="$LIBS" +LIBS="$LIBS $LDADD_LIBNTP" AC_CHECK_FUNCS([daemon]) +LIBS="$saved_LIBS" +AS_UNSET([saved_LIBS]) + AC_CHECK_FUNCS( [finite], [], @@ -979,90 +702,10 @@ AC_CHECK_FUNCS( )] ) -AC_CHECK_FUNCS([getbootfile getclock getdtablesize]) +AC_CHECK_FUNCS([getbootfile]) -AC_ARG_ENABLE( - [getifaddrs], - [AS_HELP_STRING( - [--enable-getifaddrs], - [s Enable the use of getifaddrs() [[yes|no|glibc]]. -glibc: Use getifaddrs() in glibc if you know it supports IPv6.] - )], - [want_getifaddrs="$enableval"], - [want_getifaddrs="yes"] -) -case $want_getifaddrs in - yes|glibc) - # - # Do we have getifaddrs() ? - # - case $host in - *-*linux*) - # Some recent versions of glibc support getifaddrs() which does not - # provide AF_INET6 addresses while the function provided by the USAGI - # project handles the AF_INET6 case correctly. We need to avoid - # using the former but prefer the latter unless overridden by - # --enable-getifaddrs=glibc. - case "$want_getifaddrs" in - glibc) - AC_CHECK_FUNCS([getifaddrs]) - ;; - *) - save_LIBS="$LIBS" - LIBS="-L/usr/local/v6/lib $LIBS" - AC_CHECK_LIB( - [inet6], - [getifaddrs], - [ans=yes], - [ans=no] - ) - case "$ans" in - yes) - LIBS="$LIBS -linet6" - AC_DEFINE([HAVE_GETIFADDRS], [1]) - ;; - *) - LIBS=${save_LIBS} - ;; - esac - ;; - esac - ;; - esac - ;; - *) - AC_CHECK_FUNCS([getifaddrs]) - ;; -esac - -AC_CHECK_FUNCS([getuid getrusage hstrerror]) -AC_CHECK_FUNC([gettimeofday], [], [ -case "$host" in - *-*-mpeix*) ac_cv_func_gettimeofday=yes - ;; -esac]) - -# -# Check for if_nametoindex() for IPv6 scoped addresses support -# -case "$host" in - *-hp-hpux*) - AC_SEARCH_LIBS([if_nametoindex], [ipv6]) -esac -AC_CHECK_FUNCS([if_nametoindex]) -case "$ac_cv_func_if_nametoindex" in - yes) - AC_DEFINE([ISC_PLATFORM_HAVEIFNAMETOINDEX], [1], - [ISC: do we have if_nametoindex()?]) -esac - -# We also need -lsocket, but we have tested for that already. -AC_SEARCH_LIBS([inet_ntop], [resolv], , , [-lnsl]) -AC_CHECK_FUNC([inet_ntop], [], - [AC_DEFINE([ISC_PLATFORM_NEEDNTOP], [1], [ISC: provide inet_ntop()])]) -AC_CHECK_FUNC([inet_pton], [], - [AC_DEFINE([ISC_PLATFORM_NEEDPTON], [1], [ISC: provide inet_pton()])]) +AC_CHECK_FUNCS([getuid getrusage]) case "$ac_cv_header_kvm_h" in yes) @@ -1121,14 +764,8 @@ case "$host" in *) AC_CHECK_FUNCS([sched_setscheduler]) ;; esac -AC_CHECK_FUNCS([setlinebuf setpgid setpriority setsid]) -AC_CHECK_FUNCS([settimeofday], ,[ -case "$host" in - *-*-mpeix*) ac_cv_func_settimeofday=yes - ;; -esac]) -AC_CHECK_FUNCS([setvbuf sigaction snprintf stime strdup strerror timegm]) -AC_CHECK_FUNCS([setrlimit sigvec sigset sigsuspend strchr sysconf sysctl]) +AC_CHECK_FUNCS([setlinebuf setpgid setpriority setsid setvbuf snprintf]) +AC_CHECK_FUNCS([strdup strerror setrlimit strchr]) case "$host" in *-*-aix[[456]]*) # Just stubs. Idiots. @@ -1224,28 +861,6 @@ case "$host" in ;; esac -AC_CACHE_CHECK( - [number of arguments to gettimeofday()], - [ntp_cv_func_Xettimeofday_nargs], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #include - ]], - [[ - gettimeofday(0, 0); - settimeofday(0, 0); - ]] - )], - [ntp_cv_func_Xettimeofday_nargs=2], - [ntp_cv_func_Xettimeofday_nargs=1] - )] -) -case "$ntp_cv_func_Xettimeofday_nargs" in - 1) - AC_DEFINE([SYSV_TIMEOFDAY], [1], [Does Xettimeofday take 1 arg?]) -esac - AC_CACHE_CHECK( [number of arguments taken by setpgrp()], [ntp_cv_func_setpgrp_nargs], @@ -1607,269 +1222,6 @@ case "$ntp_cv_os_wildcardreuse" in [wildcard socket needs REUSEADDR to bind interface addresses]) esac -AC_MSG_CHECKING([if we'll use clock_settime or settimeofday or stime]) -ntp_warning='GRONK' -ans=none -case "$ac_cv_func_clock_settime$ac_cv_func_settimeofday$ac_cv_func_stime" in - yes*) - ntp_warning='' - ans='clock_settime()' - ;; - noyes*) - ntp_warning='But clock_settime() would be better (if we had it)' - ans='settimeofday()' - ;; - nonoyes) - ntp_warning='Which is the worst of the three' - ans='stime()' - ;; - *) - case "$build" in - $host) - ntp_warning='Which leaves us with nothing to use!' - esac -esac -AC_MSG_RESULT([$ans]) -case "$ntp_warning" in - '') - ;; - *) - AC_MSG_WARN([*** $ntp_warning ***]) - ;; -esac - -AC_CACHE_CHECK( - [for SIGIO], - [ntp_cv_hdr_def_sigio], - [AC_EGREP_CPP( - [yes], - [ - #include - - #ifdef SIGIO - yes - #endif - ], - [ntp_cv_hdr_def_sigio=yes], - [ntp_cv_hdr_def_sigio=no] - )] - ) - -dnl Override those system that have a losing SIGIO -AC_CACHE_CHECK( - [if we want to use signalled IO], - [ntp_cv_var_signalled_io], - [ - ans=no - case "$ntp_cv_hdr_def_sigio" in - yes) - ans=yes - case "$host" in - alpha*-dec-osf4*|alpha*-dec-osf5*) - ans=no - ;; - *-convex-*) - ans=no - ;; - *-dec-*) - ans=no - ;; - *-pc-cygwin*) - ans=no - ;; - *-sni-sysv*) - ans=no - ;; - *-univel-sysv*) - ans=no - ;; - *-*-irix6*) - ans=no - ;; - *-*-freebsd*) - ans=no - ;; - *-*-*linux*) - ans=no - ;; - *-*-unicosmp*) - ans=no - ;; - *-*-kfreebsd*) - ans=no - ;; - m68k-*-mint*) - ans=no - ;; - esac - ;; - esac - ntp_cv_var_signalled_io=$ans - ] -) -case "$ntp_cv_var_signalled_io" in - yes) - AC_DEFINE([HAVE_SIGNALED_IO], [1], - [Can we use SIGIO for tcp and udp IO?]) -esac - -AC_CACHE_CHECK( - [for SIGPOLL], - [ntp_cv_hdr_def_sigpoll], - [AC_EGREP_CPP( - [yes], - [ - #include - - #ifdef SIGPOLL - yes - #endif - ], - [ntp_cv_hdr_def_sigpoll=yes], - [ntp_cv_hdr_def_sigpoll=no] - )] -) - -AC_CACHE_CHECK( - [for SIGSYS], - [ntp_cv_hdr_def_sigsys], - [AC_EGREP_CPP( - [yes], - [ - #include - - #ifdef SIGSYS - yes - #endif - ], - [ntp_cv_hdr_def_sigsys=yes], - [ntp_cv_hdr_def_sigsys=no] - )] -) - -AC_CACHE_CHECK( - [if we can use SIGPOLL for UDP I/O], - [ntp_cv_var_use_udp_sigpoll], - [ - ans=no - case "$ntp_cv_hdr_def_sigpoll" in - yes) - case "$host" in - mips-sgi-irix*) - ans=no - ;; - vax-dec-bsd) - ans=no - ;; - *-pc-cygwin*) - ans=no - ;; - *-sni-sysv*) - ans=no - ;; - *-*-aix[[456]]*) - ans=no - ;; - *-*-hpux*) - ans=no - ;; - *-*-*linux*) - ans=no - ;; - *-*-osf*) - ans=no - ;; - *-*-qnx*) - ans=no - ;; - *-*-sunos*) - ans=no - ;; - *-*-solaris*) - ans=no - ;; - *-*-ultrix*) - ans=no - ;; - *-*-unicosmp*) - ans=no - ;; - *-*-kfreebsd*) - ans=no - ;; - *) ans=yes - ;; - esac - ;; - esac - ntp_cv_var_use_udp_sigpoll=$ans - ] -) -case "$ntp_cv_var_use_udp_sigpoll" in - yes) - AC_DEFINE([USE_UDP_SIGPOLL], [1], [Can we use SIGPOLL for UDP?]) -esac - -AC_CACHE_CHECK( - [if we can use SIGPOLL for TTY I/O], - [ntp_cv_var_use_tty_sigpoll], - [ - ans=no - case "$ntp_cv_hdr_def_sigpoll" in - yes) - case "$host" in - mips-sgi-irix*) - ans=no - ;; - vax-dec-bsd) - ans=no - ;; - *-pc-cygwin*) - ans=no - ;; - *-sni-sysv*) - ans=no - ;; - *-*-aix[[456]]*) - ans=no - ;; - *-*-hpux*) - ans=no - ;; - *-*-*linux*) - ans=no - ;; - *-*-osf*) - ans=no - ;; - *-*-sunos*) - ans=no - ;; - *-*-ultrix*) - ans=no - ;; - *-*-qnx*) - ans=no - ;; - *-*-unicosmp*) - ans=no - ;; - *-*-kfreebsd*) - ans=no - ;; - *) ans=yes - ;; - esac - ;; - esac - ntp_cv_var_use_tty_sigpoll=$ans - ] -) -case "$ntp_cv_var_use_tty_sigpoll" in - yes) - AC_DEFINE([USE_TTY_SIGPOLL], [1], [Can we use SIGPOLL for tty IO?]) -esac - case "$host" in *-*-aix*) AC_DEFINE([NLIST_EXTRA_INDIRECTION], [1], @@ -2026,56 +1378,6 @@ case "$ntp_cv_struct_ppsclockev" in esac AC_MSG_RESULT([$ans]) -AC_CACHE_CHECK( - [for multicast IP support], - [ntp_cv_multicast], - [ - ntp_cv_multicast=no - case "$host" in - i386-sequent-sysv4) - ;; - *) - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #ifdef HAVE_NETINET_IN_H - # include - #endif - ]], - [[ - struct ip_mreq ipmr; - ipmr.imr_interface.s_addr = 0; - ]] - )], - [ntp_cv_multicast=yes], - [] - ) - ;; - esac - ] -) -case "$ntp_cv_multicast" in - yes) - AC_DEFINE([MCAST], [1], [Does the target support multicast IP?]) - AC_CACHE_CHECK( - [arg type needed for setsockopt() IP*_MULTICAST_LOOP], - [ntp_cv_typeof_ip_multicast_loop], - [ - case "$host" in - *-*-netbsd*|*-*-*linux*) - ntp_cv_typeof_ip_multicast_loop=u_int - ;; - *) - ntp_cv_typeof_ip_multicast_loop=u_char - ;; - esac - ] - ) - AC_DEFINE_UNQUOTED([TYPEOF_IP_MULTICAST_LOOP], - [$ntp_cv_typeof_ip_multicast_loop], - [What type to use for setsockopt]) -esac - AC_CACHE_CHECK( [availability of ntp_{adj,get}time()], [ntp_cv_var_ntp_syscalls], @@ -4276,6 +3578,7 @@ case "$build" in ;; esac +NTP_WITHSNTP AC_MSG_CHECKING([if we want to build ntpsnmpd]) AC_ARG_WITH( @@ -4668,74 +3971,6 @@ case "$ntp_signd_path" in ;; esac -AC_CHECK_HEADERS([sys/clockctl.h]) - -case "$host" in - *-*-netbsd*) - ans=yes - ;; - *) ans=no - ;; -esac - -AC_ARG_ENABLE( - [clockctl], - [AS_HELP_STRING( - [--enable-clockctl], - [s Use /dev/clockctl for non-root clock control] - )], - [ntp_use_dev_clockctl=$enableval], - [ntp_use_dev_clockctl=$ac_cv_header_sys_clockctl_h] -) - -AC_MSG_CHECKING([[if we should use /dev/clockctl]]) -AC_MSG_RESULT([$ntp_use_dev_clockctl]) - - -AC_CHECK_HEADERS([sys/capability.h sys/prctl.h]) - -AC_MSG_CHECKING([if we have linux capabilities (libcap)]) - -case "$ac_cv_header_sys_capability_h$ac_cv_header_sys_prctl_h" in - yesyes) - case "$host" in - mips-sgi-irix*) - ntp_have_linuxcaps=no - ;; - *) ntp_have_linuxcaps=yes - ;; - esac - ;; - *) - ntp_have_linuxcaps=no - ;; -esac - -AC_ARG_ENABLE( - [linuxcaps], - [AS_HELP_STRING( - [--enable-linuxcaps], - [+ Use Linux capabilities for non-root clock control] - )], - [ntp_have_linuxcaps=$enableval] -) - -AC_MSG_RESULT([$ntp_have_linuxcaps]) - -case "$ntp_have_linuxcaps" in - yes) - AC_DEFINE([HAVE_LINUX_CAPABILITIES], [1], - [Do we have Linux capabilities?]) - LIBS="$LIBS -lcap" - ;; -esac - -case "$ntp_use_dev_clockctl$ntp_have_linuxcaps" in - *yes*) - AC_DEFINE([HAVE_DROPROOT], [1], - [Can we drop root privileges?]) -esac - AC_CHECK_HEADERS([libscf.h]) LSCF= case "$ac_cv_header_libscf_h" in diff --git a/deps-ver b/deps-ver index 83750ad1b..5ec949d12 100644 --- a/deps-ver +++ b/deps-ver @@ -1 +1 @@ -Sat Jan 8 18:11:35 UTC 2011 +Mon Jan 31 21:14:28 UTC 2011 diff --git a/flock-build b/flock-build index 245071d8e..31b69c68e 100755 --- a/flock-build +++ b/flock-build @@ -82,7 +82,7 @@ do ssh $i "cd $c_d ; ./build $SIG $PARSE $STD $BUILD_ARGS" & ssh $i "cd $c_d ; ./build $SIG $PARSE $STD --disable-debugging $BUILD_ARGS" & ssh $i "cd $c_d ; ./build $SIG $PARSE $STD --without-crypto $BUILD_ARGS" & - ssh $i "cd $c_d ; ./build $SIG $STD --disable-all-clocks --disable-autokey $BUILD_ARGS" & + ssh $i "cd $c_d ; ./build $SIG $STD --disable-all-clocks --disable-autokey --without-sntp $BUILD_ARGS" & ;; 1) cat > .flockbuild-$i-$SIG <<-ENDQUOT @@ -115,7 +115,7 @@ do echo \`date -u '+%H:%M:%S'\` $i started build \$COUNT of 4 [ 0 -lt \`expr \$COUNT % $PARALLEL_BUILDS\` ] || wait - ./build $SIG $STD --disable-all-clocks --disable-autokey $BUILD_ARGS & + ./build $SIG $STD --disable-all-clocks --disable-autokey --without-sntp $BUILD_ARGS & COUNT=\`expr \$COUNT + 1\` echo \`date -u '+%H:%M:%S'\` $i started build \$COUNT of 4 diff --git a/include/Makefile.am b/include/Makefile.am index 67716b378..4f6d15386 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -14,6 +14,7 @@ noinst_HEADERS = \ hopf6039.h \ icom.h \ ieee754io.h \ + intreswork.h \ iosignal.h \ l_stdlib.h \ lib_strbuf.h \ diff --git a/include/intreswork.h b/include/intreswork.h new file mode 100644 index 000000000..c343ac013 --- /dev/null +++ b/include/intreswork.h @@ -0,0 +1,29 @@ +/* + * intreswork.h -- declarations private to ntp_intres.c, ntp_worker.c. + */ +#ifndef INTRESWORK_H +#define INTRESWORK_H + +#include "ntp_worker.h" + +#ifdef WORKER + +extern int blocking_getaddrinfo(blocking_child *, + blocking_pipe_header *); +extern int blocking_getnameinfo(blocking_child *, + blocking_pipe_header *); + +#ifdef TEST_BLOCKING_WORKER +extern void gai_test_callback(int rescode, int gai_errno, + void *context, const char *name, + const char *service, + const struct addrinfo *hints, + const struct addrinfo *ai_res); +extern void gni_test_callback(int rescode, int gni_errno, + sockaddr_u *psau, int flags, + const char *host, + const char *service, void *context); +#endif /* TEST_BLOCKING_WORKER */ +#endif /* WORKER */ + +#endif /* INTRESWORK_H */ diff --git a/include/libntp.h b/include/libntp.h index 2b868316b..f20a03f0d 100644 --- a/include/libntp.h +++ b/include/libntp.h @@ -2,7 +2,9 @@ #if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) #define GETDTABLESIZE() ((int)sysconf(_SC_OPEN_MAX)) -#elif !defined(HAVE_GETDTABLESIZE) +#elif defined(HAVE_GETDTABLESIZE) +#define GETDTABLESIZE getdtablesize +#else /* * if we have no idea about the max fd value set up things * so we will start at FOPEN_MAX diff --git a/include/ntp_calendar.h b/include/ntp_calendar.h index 012fb1be9..d97892116 100644 --- a/include/ntp_calendar.h +++ b/include/ntp_calendar.h @@ -4,6 +4,8 @@ #ifndef NTP_CALENDAR_H #define NTP_CALENDAR_H +#include + #include "ntp_types.h" /* gregorian calendar date */ diff --git a/include/ntp_control.h b/include/ntp_control.h index 3d2e1a669..102e2f0b4 100644 --- a/include/ntp_control.h +++ b/include/ntp_control.h @@ -4,6 +4,11 @@ #include "ntp_types.h" +typedef union ctl_pkt_u_tag { + u_char data[480 + MAX_MAC_LEN]; /* data + auth */ + u_int32 u32[(480 + MAX_MAC_LEN) / sizeof(u_int32)]; +} ctl_pkt_u; + struct ntp_control { u_char li_vn_mode; /* leap, version, mode */ u_char r_m_e_op; /* response, more, error, opcode */ @@ -12,13 +17,13 @@ struct ntp_control { associd_t associd; /* association ID */ u_short offset; /* offset of this batch of data */ u_short count; /* count of data in this packet */ - u_char data[(480 + MAX_MAC_LEN)]; /* data + auth */ + ctl_pkt_u u; }; /* * Length of the control header, in octets */ -#define CTL_HEADER_LEN (offsetof(struct ntp_control, data)) +#define CTL_HEADER_LEN (offsetof(struct ntp_control, u)) #define CTL_MAX_DATA_LEN 468 diff --git a/include/ntp_debug.h b/include/ntp_debug.h index d07323b85..e9e3f0364 100644 --- a/include/ntp_debug.h +++ b/include/ntp_debug.h @@ -9,6 +9,7 @@ #define NTP_DEBUG_H #include "ntp_assert.h" +#include "ntp_stdlib.h" /* * macros for debugging output - cut down on #ifdef pollution in the code @@ -18,7 +19,7 @@ #define DPRINTF(_lvl_, _arg_) \ do { \ if (debug >= (_lvl_)) \ - printf _arg_; \ + mprintf _arg_; \ } while (0) #else #define DPRINTF(_lvl_, _arg_) do {} while (0) diff --git a/include/ntp_intres.h b/include/ntp_intres.h index fe63409a3..1b6bd66e0 100644 --- a/include/ntp_intres.h +++ b/include/ntp_intres.h @@ -1,23 +1,45 @@ +/* + * ntp_intres.h - client interface to blocking-worker name resolution. + */ #ifndef NTP_INTRES_H #define NTP_INTRES_H -#include "ntp_worker.h" +#include #ifdef WORKER +#define INITIAL_DNS_RETRY 2 /* seconds between queries */ -extern int blocking_getaddrinfo(blocking_pipe_header *); -extern int blocking_getnameinfo(blocking_pipe_header *); +/* + * you call getaddrinfo_sometime(name, service, &hints, retry, callback_func, context); + * later (*callback_func)(rescode, gai_errno, context, name, service, hints, ai_result) is called. + */ +typedef void (*gai_sometime_callback) + (int, int, void *, const char *, const char *, + const struct addrinfo *, const struct addrinfo *); +extern int getaddrinfo_sometime(const char *, const char *, + const struct addrinfo *, int, + gai_sometime_callback, void *); +/* + * In gai_sometime_callback routines, the resulting addrinfo list is + * only available until the callback returns. To hold on to the list + * of addresses after the callback returns, use copy_addrinfo_list(): + * + * struct addrinfo *copy_addrinfo_list(const struct addrinfo *); + */ -#ifdef TEST_BLOCKING_WORKER -extern void gai_test_callback(int rescode, int gai_errno, - void *context, const char *name, - const char *service, - const struct addrinfo *hints, - const struct addrinfo *ai_res); -extern void gni_test_callback(int rescode, int gni_errno, - sockaddr_u *psau, int flags, - const char *host, - const char *service, void *context); -#endif /* TEST_BLOCKING_WORKER */ + +/* + * you call getnameinfo_sometime(sockaddr, namelen, servlen, flags, callback_func, context); + * later (*callback_func)(rescode, gni_errno, sockaddr, flags, name, service, context) is called. + */ +typedef void (*gni_sometime_callback) + (int, int, sockaddr_u *, int, const char *, + const char *, void *); +extern int getnameinfo_sometime(sockaddr_u *, size_t, size_t, int, + gni_sometime_callback, void *); #endif /* WORKER */ -#endif /* !NTP_INTRES_H */ + +/* intres_timeout_req() is provided by the client, ntpd or sntp. */ +extern void intres_timeout_req(u_int); + +#endif /* NTP_INTRES_H */ diff --git a/include/ntp_io.h b/include/ntp_io.h index c76e52bcf..2cdca7108 100644 --- a/include/ntp_io.h +++ b/include/ntp_io.h @@ -88,11 +88,10 @@ extern void add_nic_rule(nic_rule_match match_type, const char *if_name, int prefixlen, nic_rule_action action); #ifndef HAVE_IO_COMPLETION_PORT -extern void close_all_beyond(int); -extern void close_all_except(int); -#endif -#ifdef WORK_FORK -extern void update_resp_pipe_fd(int, int); +extern void maintain_activefds(int fd, int closing); +#else +#define maintain_activefds(f, c) do {} while (0) #endif + #endif /* NTP_IO_H */ diff --git a/include/ntp_lists.h b/include/ntp_lists.h index 465782051..76d9351b4 100644 --- a/include/ntp_lists.h +++ b/include/ntp_lists.h @@ -158,8 +158,8 @@ do { \ entrytype **ppentry; \ \ ppentry = &(listhead); \ - while (*ppentry != NULL) { \ - if (beforecur) { \ + while (TRUE) { \ + if (NULL == *ppentry || (beforecur)) { \ (pentry)->nextlink = *ppentry; \ *ppentry = (pentry); \ break; \ @@ -171,7 +171,7 @@ do { \ break; \ } \ } \ -} while (0) +} while (FALSE) #define UNLINK_HEAD_SLIST(punlinked, listhead, nextlink) \ do { \ diff --git a/include/ntp_machine.h b/include/ntp_machine.h index 10160ea60..6fa7412b5 100644 --- a/include/ntp_machine.h +++ b/include/ntp_machine.h @@ -10,17 +10,7 @@ #ifndef NTP_MACHINE_H #define NTP_MACHINE_H -#ifdef TIME_WITH_SYS_TIME -# include -# include -#else -# ifdef HAVE_SYS_TIME_H -# include -# else -# include -# endif -#endif - +#include "ntp_unixtime.h" #include "ntp_proto.h" /* diff --git a/include/ntp_refclock.h b/include/ntp_refclock.h index 933d6b9e8..976c6f3c6 100644 --- a/include/ntp_refclock.h +++ b/include/ntp_refclock.h @@ -98,7 +98,7 @@ struct refclockio { to avoid excessive buffer use due to small bursts of refclock input data */ - caddr_t srcclock; /* pointer to clock structure */ + struct peer *srcclock; /* refclock peer */ int datalen; /* length of data */ int fd; /* file descriptor */ u_long recvcount; /* count of receive completions */ @@ -130,25 +130,10 @@ struct refclockbug { #define GMT 0 /* I hope nobody sees this */ #define MAXDIAL 60 /* max length of modem dial strings */ -/* - * Line discipline flags. These require line discipline or streams - * modules to be installed/loaded in the kernel. If specified, but not - * installed, the code runs as if unspecified. - */ -#define LDISC_STD 0x00 /* standard */ -#define LDISC_CLK 0x01 /* tty_clk \n intercept */ -#define LDISC_CLKPPS 0x02 /* tty_clk \377 intercept */ -#define LDISC_ACTS 0x04 /* tty_clk #* intercept */ -#define LDISC_CHU 0x08 /* depredated */ -#define LDISC_PPS 0x10 /* ppsclock, ppsapi */ -#define LDISC_RAW 0x20 /* raw binary */ -#define LDISC_ECHO 0x40 /* enable echo */ -#define LDISC_REMOTE 0x80 /* remote mode */ -#define LDISC_7O1 0x100 /* 7-bit, odd parity for Z3801A */ struct refclockproc { struct refclockio io; /* I/O handler structure */ - caddr_t unitptr; /* pointer to unit structure */ + void * unitptr; /* pointer to unit structure */ u_char leap; /* leap/synchronization code */ u_char currentstatus; /* clock status */ u_char lastevent; /* last exception event */ diff --git a/include/ntp_request.h b/include/ntp_request.h index 7aa4fa4ee..8041cd066 100644 --- a/include/ntp_request.h +++ b/include/ntp_request.h @@ -122,6 +122,11 @@ union addrun struct in_addr addr; }; +typedef union req_data_u_tag { + u_int32 u32[(MAXFILENAME + 48) / sizeof(u_int32)]; + char data[MAXFILENAME + 48]; /* data area [32 prev](176 byte max) */ +} req_data_u; /* struct conf_peer must fit */ + /* * A request packet. These are almost a fixed length. */ @@ -132,8 +137,7 @@ struct req_pkt { u_char request; /* request number */ u_short err_nitems; /* error code/number of data items */ u_short mbz_itemsize; /* item size */ - char data[MAXFILENAME + 48]; /* data area [32 prev](176 byte max) */ - /* struct conf_peer must fit */ + req_data_u u; /* data area */ l_fp tstamp; /* time stamp, for authentication */ keyid_t keyid; /* (optional) encryption key */ char mac[MAX_MAC_LEN-sizeof(keyid_t)]; /* (optional) auth code */ @@ -150,7 +154,7 @@ struct req_pkt_tail { }; /* MODE_PRIVATE request packet header length before optional items. */ -#define REQ_LEN_HDR (offsetof(struct req_pkt, data)) +#define REQ_LEN_HDR (offsetof(struct req_pkt, u)) /* MODE_PRIVATE request packet fixed length without MAC. */ #define REQ_LEN_NOMAC (offsetof(struct req_pkt, keyid)) /* MODE_PRIVATE req_pkt_tail minimum size (16 octet digest) */ @@ -162,8 +166,13 @@ struct req_pkt_tail { * is a maximally sized one. Note that this implementation doesn't * authenticate responses. */ -#define RESP_HEADER_SIZE (offsetof(struct resp_pkt, data)) -#define RESP_DATA_SIZE (500) +#define RESP_HEADER_SIZE (offsetof(struct resp_pkt, u)) +#define RESP_DATA_SIZE 500 + +typedef union resp_pkt_u_tag { + char data[RESP_DATA_SIZE]; + u_int32 u32[RESP_DATA_SIZE / sizeof(u_int32)]; +} resp_pkt_u; struct resp_pkt { u_char rm_vn_mode; /* response, more, version, mode */ @@ -172,7 +181,7 @@ struct resp_pkt { u_char request; /* request number */ u_short err_nitems; /* error code/number of data items */ u_short mbz_itemsize; /* item size */ - char data[RESP_DATA_SIZE]; /* data area */ + resp_pkt_u u; /* data area */ }; @@ -890,26 +899,26 @@ struct info_kernel { * interface statistics */ struct info_if_stats { - union addrun unaddr; /* address */ - union addrun unbcast; /* broadcast */ - union addrun unmask; /* mask */ - u_int32 v6_flag; /* is this v6 */ + union addrun unaddr; /* address */ + union addrun unbcast; /* broadcast */ + union addrun unmask; /* mask */ + u_int32 v6_flag; /* is this v6 */ char name[32]; /* name of interface */ int32 flags; /* interface flags */ int32 last_ttl; /* last TTL specified */ int32 num_mcast; /* No. of IP addresses in multicast socket */ - int32 received; /* number of incoming packets */ + int32 received; /* number of incoming packets */ int32 sent; /* number of outgoing packets */ int32 notsent; /* number of send failures */ - int32 uptime; /* number of seconds this interface was active */ + int32 uptime; /* number of seconds this interface was active */ u_int32 scopeid; /* Scope used for Multicasting */ u_int32 ifindex; /* interface index - from system */ - u_int32 ifnum; /* sequential interface number */ - u_int32 peercnt; /* number of peers referencinf this interface - informational only */ + u_int32 ifnum; /* sequential interface number */ + u_int32 peercnt; /* number of peers referencinf this interface - informational only */ u_short family; /* Address family */ - u_char ignore_packets; /* Specify whether the packet should be ignored */ - u_char action; /* reason the item is listed */ - int32 _filler0; /* pad to a 64 bit size boundary */ + u_char ignore_packets; /* Specify whether the packet should be ignored */ + u_char action; /* reason the item is listed */ + int32 _filler0; /* pad to a 64 bit size boundary */ }; #define IFS_EXISTS 1 /* just exists */ diff --git a/include/ntp_rfc2553.h b/include/ntp_rfc2553.h index 337658720..08ccbc415 100644 --- a/include/ntp_rfc2553.h +++ b/include/ntp_rfc2553.h @@ -74,6 +74,12 @@ #include "ntp_types.h" #include "ntp_malloc.h" +struct addrinfo *copy_addrinfo_impl(const struct addrinfo * +#ifdef EREALLOC_CALLSITE /* from ntp_malloc.h */ + , + const char *, int +#endif + ); struct addrinfo *copy_addrinfo_list_impl(const struct addrinfo * #ifdef EREALLOC_CALLSITE /* from ntp_malloc.h */ , @@ -81,9 +87,12 @@ struct addrinfo *copy_addrinfo_list_impl(const struct addrinfo * #endif ); #ifdef EREALLOC_CALLSITE +# define copy_addrinfo(l) \ + copy_addrinfo_impl((l), __FILE__, __LINE__) # define copy_addrinfo_list(l) \ copy_addrinfo_list_impl((l), __FILE__, __LINE__) #else +# define copy_addrinfo(l) copy_addrinfo_impl(l) # define copy_addrinfo_list(l) copy_addrinfo_list_impl(l) #endif diff --git a/include/ntp_stdlib.h b/include/ntp_stdlib.h index b147be06a..846a57957 100644 --- a/include/ntp_stdlib.h +++ b/include/ntp_stdlib.h @@ -32,11 +32,22 @@ # endif #endif -extern int mvsnprintf(char *, size_t, const char *, va_list); +extern int mprintf(const char *, ...) + __attribute__((__format__(__printf__, 1, 2))); +extern int mfprintf(FILE *, const char *, ...) + __attribute__((__format__(__printf__, 2, 3))); +extern int mvfprintf(FILE *, const char *, va_list) + __attribute__((__format__(__printf__, 2, 0))); +extern int mvsnprintf(char *, size_t, const char *, va_list) + __attribute__((__format__(__printf__, 3, 0))); extern int msnprintf(char *, size_t, const char *, ...) - __attribute__((__format__(__printf__, 3, 4))); + __attribute__((__format__(__printf__, 3, 4))); extern void msyslog(int, const char *, ...) - __attribute__((__format__(__printf__, 2, 3))); + __attribute__((__format__(__printf__, 2, 3))); +extern void init_logging (const char *, u_long, const char *, + int); +extern int change_logfile (const char *, const char *); +extern void setup_logfile (const char *, const char *); #ifndef errno_to_str extern void errno_to_str(int, char *, size_t); #endif diff --git a/include/ntp_tty.h b/include/ntp_tty.h index 828006389..ec7448683 100644 --- a/include/ntp_tty.h +++ b/include/ntp_tty.h @@ -78,16 +78,16 @@ * modules to be installed/loaded in the kernel. If specified, but not * installed, the code runs as if unspecified. */ -#define LDISC_STD 0x00 /* standard */ -#define LDISC_CLK 0x01 /* tty_clk \n intercept */ -#define LDISC_CLKPPS 0x02 /* tty_clk \377 intercept */ -#define LDISC_ACTS 0x04 /* tty_clk #* intercept */ -#define LDISC_CHU 0x08 /* depredated */ -#define LDISC_PPS 0x10 /* ppsclock, ppsapi */ -#define LDISC_RAW 0x20 /* raw binary */ -#define LDISC_ECHO 0x40 /* enable echo */ -#define LDISC_REMOTE 0x80 /* remote mode */ -#define LDISC_7O1 0x100 /* 7-bit, odd parity for Z3801A */ +#define LDISC_STD 0x000 /* standard */ +#define LDISC_CLK 0x001 /* tty_clk \n intercept */ +#define LDISC_CLKPPS 0x002 /* tty_clk \377 intercept */ +#define LDISC_ACTS 0x004 /* tty_clk #* intercept */ +#define LDISC_CHU 0x008 /* depredated */ +#define LDISC_PPS 0x010 /* ppsclock, ppsapi */ +#define LDISC_RAW 0x020 /* raw binary */ +#define LDISC_ECHO 0x040 /* enable echo */ +#define LDISC_REMOTE 0x080 /* remote mode */ +#define LDISC_7O1 0x100 /* 7-bit, odd parity for Z3801A */ /* function prototypes for ntp_tty.c */ #if !defined(SYS_VXWORKS) && !defined(SYS_WINNT) diff --git a/include/ntp_unixtime.h b/include/ntp_unixtime.h index a4ba7d7fe..1db9e5ab8 100644 --- a/include/ntp_unixtime.h +++ b/include/ntp_unixtime.h @@ -6,11 +6,12 @@ #ifndef NTP_UNIXTIME_H #define NTP_UNIXTIME_H -#include "ntp_types.h" - -#ifdef SIM -#include "ntpsim.h" +#ifdef HAVE_SYS_TIME_H +# include #endif +#include + +#include "ntp_types.h" #ifdef SIM # define GETTIMEOFDAY(a, b) (node_gettime(&ntp_node, a)) @@ -22,7 +23,7 @@ # if defined(HAVE_SYS_TIMERS_H) && defined(HAVE_GETCLOCK) # include int getclock (int clock_type, struct timespec *tp); -/* Don't #define GETTIMEOFDAY because we shouldn't be using it in this case. */ +# define GETTIMEOFDAY(a, b) (gettimeofday(a, b)) # define SETTIMEOFDAY(a, b) (settimeofday(a, b)) # else /* not (HAVE_SYS_TIMERS_H && HAVE_GETCLOCK) */ # ifdef SYSV_TIMEOFDAY diff --git a/include/ntp_worker.h b/include/ntp_worker.h index 23032587c..beca44f62 100644 --- a/include/ntp_worker.h +++ b/include/ntp_worker.h @@ -8,6 +8,12 @@ #include "ntp_workimpl.h" #ifdef WORKER +# if defined(WORK_THREAD) && defined(WORK_PIPE) +# ifdef HAVE_SEMAPHORE_H +# include +# endif +# endif +#include "ntp_stdlib.h" /* #define TEST_BLOCKING_WORKER */ /* ntp_config.c ntp_intres.c */ @@ -31,22 +37,126 @@ typedef struct blocking_pipe_header_tag { size_t octets; blocking_magic_sig magic_sig; blocking_work_req rtype; + u_int child_idx; blocking_work_callback done_func; void * context; } blocking_pipe_header; -extern int intres_req_pending; +# ifdef WORK_THREAD +# ifdef WORK_PIPE +typedef pthread_t * thr_ref; +typedef sem_t * sem_ref; +# else +typedef HANDLE thr_ref; +typedef HANDLE sem_ref; +# endif +# endif -extern int queue_blocking_request(blocking_work_req, void *, size_t, blocking_work_callback, void *); -extern int queue_blocking_response(blocking_pipe_header *, size_t, const blocking_pipe_header *); -extern int send_blocking_req_internal(blocking_pipe_header *, void *); -extern int send_blocking_resp_internal(blocking_pipe_header *); -extern blocking_pipe_header *receive_blocking_req_internal(void); -extern blocking_pipe_header *receive_blocking_resp_internal(void); -extern int blocking_child_common (void); -extern void exit_worker(int); -extern int worker_sleep(time_t); +/* + * + */ +#ifdef WORK_FORK +typedef struct blocking_child_tag { + int reusable; + int pid; + int req_write_pipe; /* parent */ + int resp_read_pipe; + void * resp_read_ctx; + int req_read_pipe; /* child */ + int resp_write_pipe; + int ispipe; +} blocking_child; +#elif defined(WORK_THREAD) +typedef struct blocking_child_tag { +/* + * blocking workitems and blocking_responses are dynamically-sized + * one-dimensional arrays of pointers to blocking worker requests and + * responses. + */ + int reusable; + thr_ref thread_ref; + u_int thread_id; + blocking_pipe_header * volatile * volatile + workitems; + volatile size_t workitems_alloc; + size_t next_workitem; /* parent */ + size_t next_workeritem; /* child */ + blocking_pipe_header * volatile * volatile + responses; + volatile size_t responses_alloc; + size_t next_response; /* child */ + size_t next_workresp; /* parent */ + /* event handles / sem_t pointers */ + /* sem_ref child_is_blocking; */ + sem_ref blocking_req_ready; + sem_ref wake_scheduled_sleep; +#ifdef WORK_PIPE + int resp_read_pipe; /* parent */ + int resp_write_pipe;/* child */ + int ispipe; + void * resp_read_ctx; /* child */ +#else + sem_ref blocking_response_ready; +#endif +} blocking_child; + +#endif /* WORK_THREAD */ + +extern blocking_child ** blocking_children; +extern size_t blocking_children_alloc; +extern int worker_per_query; /* boolean */ +extern int intres_req_pending; + +extern u_int available_blocking_child_slot(void); +extern int queue_blocking_request(blocking_work_req, void *, + size_t, blocking_work_callback, + void *); +extern int queue_blocking_response(blocking_child *, + blocking_pipe_header *, size_t, + const blocking_pipe_header *); +extern void process_blocking_resp(blocking_child *); +extern int send_blocking_req_internal(blocking_child *, + blocking_pipe_header *, + void *); +extern int send_blocking_resp_internal(blocking_child *, + blocking_pipe_header *); +extern blocking_pipe_header * + receive_blocking_req_internal(blocking_child *); +extern blocking_pipe_header * + receive_blocking_resp_internal(blocking_child *); +extern int blocking_child_common(blocking_child *); +extern void exit_worker(int) + __attribute__ ((__noreturn__)); +extern int worker_sleep(blocking_child *, time_t); +extern void worker_idle_timer_fired(void); +extern void interrupt_worker_sleep(void); +extern int req_child_exit(blocking_child *); +#ifndef HAVE_IO_COMPLETION_PORT +extern int pipe_socketpair(int fds[2], int *is_pipe); +extern void close_all_beyond(int); +extern void close_all_except(int); +extern void kill_asyncio (int); +#endif + +# ifdef WORK_PIPE +typedef void (*addremove_io_fd_func)(int, int, int); +extern addremove_io_fd_func addremove_io_fd; +# else +extern void handle_blocking_resp_sem(void *); +typedef void (*addremove_io_semaphore_func)(sem_ref, int); +extern addremove_io_semaphore_func addremove_io_semaphore; +# endif + +# ifdef WORK_FORK +extern int worker_process; +# endif #endif /* WORKER */ +#if defined(HAVE_DROPROOT) && defined(WORK_FORK) +extern void fork_deferred_worker(void); +#else +# define fork_deferred_worker() do {} while (0) +#endif + #endif /* !NTP_WORKER_H */ diff --git a/include/ntp_workimpl.h b/include/ntp_workimpl.h index ddba76a74..a86c2cd0b 100644 --- a/include/ntp_workimpl.h +++ b/include/ntp_workimpl.h @@ -11,15 +11,20 @@ */ #if defined(SYS_WINNT) # define WORK_THREAD +#elif defined(ISC_PLATFORM_USETHREADS) && \ + defined(HAVE_SEM_TIMEDWAIT) && \ + (defined(HAVE_GETCLOCK) || defined(HAVE_CLOCK_GETTIME)) +# define WORK_THREAD +# define WORK_PIPE #elif defined(VMS) || defined(SYS_VXWORKS) /* empty */ #elif defined(HAVE_WORKING_FORK) # define WORK_FORK +# define WORK_PIPE #endif #if defined(WORK_FORK) || defined(WORK_THREAD) # define WORKER #endif - #endif /* !NTP_WORKIMPL_H */ diff --git a/include/ntpd.h b/include/ntpd.h index 4bca7214e..7c27c3a52 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -15,7 +15,7 @@ #include "ntp_select.h" #include "ntp_malloc.h" #include "ntp_refclock.h" -#include "ntp_workimpl.h" +#include "ntp_intres.h" #include "recvbuff.h" /* @@ -41,9 +41,6 @@ extern u_short ctlpeerstatus (struct peer *); extern int ctlsettrap (sockaddr_u *, struct interface *, int, int); extern u_short ctlsysstatus (void); extern void init_control (void); -extern void init_logging (const char *, int); -extern int change_logfile (const char *, int); -extern void setup_logfile (int); extern void process_control (struct recvbuf *, int); extern void report_event (int, struct peer *, const char *); extern int mprintf_event (int, struct peer *, const char *, ...) @@ -79,40 +76,6 @@ extern void set_var (struct ctl_var **, const char *, u_long, u_short); extern void set_sys_var (const char *, u_long, u_short); extern const char * get_ext_sys_var(const char *tag); -/* ntp_intres.c */ -#ifdef WORKER -#define INITIAL_DNS_RETRY 2 /* seconds between queries */ - -/* - * you call getaddrinfo_sometime(name, service, &hints, retry, callback_func, context); - * later (*callback_func)(rescode, gai_errno, context, name, service, hints, ai_result) is called. - */ -typedef void (*gai_sometime_callback) - (int, int, void *, const char *, const char *, - const struct addrinfo *, const struct addrinfo *); -extern int getaddrinfo_sometime(const char *, const char *, - const struct addrinfo *, int, - gai_sometime_callback, void *); -/* - * In gai_sometime_callback routines, the resulting addrinfo list is - * only available until the callback returns. To hold on to the list - * of addresses after the callback returns, use copy_addrinfo_list(): - * - * struct addrinfo *copy_addrinfo_list(const struct addrinfo *); - */ - - -/* - * you call getnameinfo_sometime(sockaddr, namelen, servlen, flags, callback_func, context); - * later (*callback_func)(rescode, gni_errno, sockaddr, flags, name, service, context) is called. - */ -typedef void (*gni_sometime_callback) - (int, int, sockaddr_u *, int, const char *, - const char *, void *); -extern int getnameinfo_sometime(sockaddr_u *, size_t, size_t, int, - gni_sometime_callback, void *); -#endif /* WORKER */ - /* ntp_io.c */ typedef struct interface_info { endpt * ep; @@ -138,9 +101,6 @@ extern void io_unsetbclient (void); extern void io_multicast_add(sockaddr_u *); extern void io_multicast_del(sockaddr_u *); extern void sendpkt (sockaddr_u *, struct interface *, int, struct pkt *, int); -#ifndef SYS_WINNT -extern void kill_asyncio (int); -#endif #ifdef DEBUG extern void collect_timing (struct recvbuf *, const char *, int, l_fp *); #endif @@ -280,7 +240,6 @@ extern void timer (void); extern void timer_clr_stats (void); extern void timer_interfacetimeout (u_long); extern volatile int interface_interval; -extern u_long worker_idle_timer; /* next check current_time */ extern u_long orphwait; /* orphan wait time */ #ifdef AUTOKEY extern char *sys_hostname; /* host name */ @@ -308,18 +267,6 @@ extern void record_timing_stats (const char *); #endif extern char * fstostr(time_t); /* NTP timescale seconds */ -/* ntp_worker.c */ -#ifdef WORKER -extern void process_blocking_response(void); -extern void worker_idle_timer_fired(void); -extern void interrupt_worker_sleep(void); -#endif /* WORKER */ -#if defined(HAVE_DROPROOT) && defined(WORK_FORK) -extern void fork_deferred_worker(void); -#else -# define fork_deferred_worker() do {} while (0) -#endif - /* ntpd.c */ extern void parse_cmdline_opts(int *, char ***); @@ -551,6 +498,9 @@ extern u_long current_time; /* seconds since startup */ extern u_long timer_timereset; extern u_long timer_overflows; extern u_long timer_xmtcalls; +#ifdef SYS_WINNT +HANDLE WaitableTimerHandle; +#endif /* ntp_util.c */ extern int stats_control; /* write stats to fileset? */ @@ -558,13 +508,6 @@ extern int stats_write_period; /* # of seconds between writes. */ extern double stats_write_tolerance; extern double wander_threshold; -/* ntp_worker.c */ -#if defined(WORK_FORK) -extern int parent_resp_read_pipe; -#elif defined (WORK_THREAD) -extern HANDLE blocking_response_ready; -#endif - /* ntpd.c */ extern volatile int debug; /* debugging flag */ extern int nofork; /* no-fork flag */ diff --git a/include/recvbuff.h b/include/recvbuff.h index 1099ceaa8..5f925f8ae 100644 --- a/include/recvbuff.h +++ b/include/recvbuff.h @@ -2,7 +2,7 @@ #define RECVBUFF_H #include "ntp.h" -#include "ntp_fp.h" +#include "ntp_net.h" #include "ntp_lists.h" #include diff --git a/lib/isc/pthreads/mutex.c b/lib/isc/pthreads/mutex.c index b57d9eee8..614d2c757 100644 --- a/lib/isc/pthreads/mutex.c +++ b/lib/isc/pthreads/mutex.c @@ -30,6 +30,15 @@ #include #include +#if HAVE_PTHREADS < 5 /* HP-UX 10.20 has 4, needs this */ +# define pthread_mutex_init(m, a) \ + pthread_mutex_init(m, (a) \ + ? *(const pthread_mutexattr_t *)(a) \ + : pthread_mutexattr_default) +# define PTHREAD_MUTEX_RECURSIVE MUTEX_RECURSIVE_NP +# define pthread_mutexattr_settype pthread_mutexattr_setkind_np +#endif + #if ISC_MUTEX_PROFILE /*@{*/ diff --git a/lib/isc/unix/ifiter_ioctl.c b/lib/isc/unix/ifiter_ioctl.c index a69979326..b69c18d23 100644 --- a/lib/isc/unix/ifiter_ioctl.c +++ b/lib/isc/unix/ifiter_ioctl.c @@ -453,7 +453,7 @@ internal_current4(isc_interfaceiter_t *iter) { INSIST( iter->pos < (unsigned int) iter->ifc.ifc_len); - ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos); + ifrp = (void *)((char *) iter->ifc.ifc_req + iter->pos); memset(&ifreq, 0, sizeof(ifreq)); memcpy(&ifreq, ifrp, sizeof(ifreq)); @@ -666,7 +666,7 @@ internal_current6(isc_interfaceiter_t *iter) { return (iter->result6); REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len); - ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6); + ifrp = (void *)((char *)iter->lifc.lifc_req + iter->pos6); memset(&lifreq, 0, sizeof(lifreq)); memcpy(&lifreq, ifrp, sizeof(lifreq)); diff --git a/lib/isc/unix/interfaceiter.c b/lib/isc/unix/interfaceiter.c index 3524a02c6..cdc8ac13f 100644 --- a/lib/isc/unix/interfaceiter.c +++ b/lib/isc/unix/interfaceiter.c @@ -80,11 +80,11 @@ get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src, switch (family) { case AF_INET: memcpy(&dst->type.in, - &((struct sockaddr_in *) src)->sin_addr, + &((struct sockaddr_in *)(void *)src)->sin_addr, sizeof(struct in_addr)); break; case AF_INET6: - sa6 = (struct sockaddr_in6 *)src; + sa6 = (struct sockaddr_in6 *)(void *)src; memcpy(&dst->type.in6, &sa6->sin6_addr, sizeof(struct in6_addr)); #ifdef ISC_PLATFORM_HAVESCOPEID diff --git a/libntp/Makefile.am b/libntp/Makefile.am index 17b32266b..93574fa21 100644 --- a/libntp/Makefile.am +++ b/libntp/Makefile.am @@ -4,6 +4,42 @@ BUILT_SOURCES = CLEANFILES = noinst_LIBRARIES = libntp.a @MAKE_LIBNTPSIM@ EXTRA_LIBRARIES = libntpsim.a + +libisc_SRCS = \ + $(srcdir)/../lib/isc/assertions.c \ + $(srcdir)/../lib/isc/buffer.c \ + $(srcdir)/../lib/isc/@LIBISC_PTHREADS_NOTHREADS@/condition.c \ + $(srcdir)/../lib/isc/unix/dir.c \ + $(srcdir)/../lib/isc/error.c \ + $(srcdir)/../lib/isc/unix/errno2result.c \ + $(srcdir)/../lib/isc/event.c \ + $(srcdir)/../lib/isc/unix/file.c \ + $(srcdir)/../lib/isc/inet_ntop.c \ + $(srcdir)/../lib/isc/inet_pton.c \ + $(srcdir)/../lib/isc/unix/interfaceiter.c \ + $(srcdir)/../lib/isc/lib.c \ + $(srcdir)/../lib/isc/log.c \ + $(srcdir)/../lib/isc/md5.c \ + $(srcdir)/../lib/isc/nls/msgcat.c \ + $(srcdir)/../lib/isc/unix/net.c \ + $(srcdir)/../lib/isc/netaddr.c \ + $(srcdir)/../lib/isc/netscope.c \ + $(srcdir)/../lib/isc/ondestroy.c \ + $(srcdir)/../lib/isc/random.c \ + $(srcdir)/../lib/isc/result.c \ + $(srcdir)/../lib/isc/unix/stdio.c \ + $(srcdir)/../lib/isc/unix/stdtime.c \ + $(srcdir)/../lib/isc/unix/strerror.c \ + $(srcdir)/../lib/isc/task.c \ + $(srcdir)/../lib/isc/@LIBISC_PTHREADS_NOTHREADS@/thread.c \ + $(srcdir)/../lib/isc/unix/time.c \ + $(srcdir)/../lib/isc/sockaddr.c \ + $(NULL) + +if PTHREADS +libisc_SRCS += $(srcdir)/../lib/isc/pthreads/mutex.c +endif + libntp_a_SRCS = \ a_md5encrypt.c \ adjtime.c \ @@ -46,9 +82,11 @@ libntp_a_SRCS = \ msyslog.c \ netof.c \ ntp_calendar.c \ + ntp_intres.c \ ntp_libopts.c \ ntp_lineedit.c \ ntp_rfc2553.c \ + ntp_worker.c \ numtoa.c \ numtohost.c \ octtoint.c \ @@ -71,36 +109,12 @@ libntp_a_SRCS = \ tvtots.c \ uglydate.c \ uinttoa.c \ + work_fork.c \ + work_thread.c \ ymd2yd.c \ - $(srcdir)/../lib/isc/assertions.c \ - $(srcdir)/../lib/isc/buffer.c \ - $(srcdir)/../lib/isc/nothreads/condition.c \ - $(srcdir)/../lib/isc/unix/dir.c \ - $(srcdir)/../lib/isc/error.c \ - $(srcdir)/../lib/isc/unix/errno2result.c \ - $(srcdir)/../lib/isc/event.c \ - $(srcdir)/../lib/isc/unix/file.c \ - $(srcdir)/../lib/isc/inet_ntop.c \ - $(srcdir)/../lib/isc/inet_pton.c \ - $(srcdir)/../lib/isc/unix/interfaceiter.c \ - $(srcdir)/../lib/isc/lib.c \ - $(srcdir)/../lib/isc/log.c \ - $(srcdir)/../lib/isc/md5.c \ - $(srcdir)/../lib/isc/nls/msgcat.c \ - $(srcdir)/../lib/isc/unix/net.c \ - $(srcdir)/../lib/isc/netaddr.c \ - $(srcdir)/../lib/isc/netscope.c \ - $(srcdir)/../lib/isc/ondestroy.c \ - $(srcdir)/../lib/isc/random.c \ - $(srcdir)/../lib/isc/result.c \ - $(srcdir)/../lib/isc/unix/stdio.c \ - $(srcdir)/../lib/isc/unix/stdtime.c \ - $(srcdir)/../lib/isc/unix/strerror.c \ - $(srcdir)/../lib/isc/task.c \ - $(srcdir)/../lib/isc/nothreads/thread.c \ - $(srcdir)/../lib/isc/unix/time.c \ - $(srcdir)/../lib/isc/sockaddr.c \ + $(libisc_SRCS) \ $(NULL) + libntp_a_SOURCES = systime.c $(libntp_a_SRCS) libntpsim_a_SOURCES = systime_s.c $(libntp_a_SRCS) EXTRA_libntp_a_SOURCES = adjtimex.c @@ -108,7 +122,7 @@ ETAGS_ARGS = Makefile.am INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += $(LIBOPTS_CFLAGS) diff --git a/libntp/a_md5encrypt.c b/libntp/a_md5encrypt.c index dc23fce38..60695a169 100644 --- a/libntp/a_md5encrypt.c +++ b/libntp/a_md5encrypt.c @@ -100,6 +100,6 @@ addr2refid(sockaddr_u *addr) EVP_DigestUpdate(&ctx, (u_char *)PSOCK_ADDR6(addr), sizeof(struct in6_addr)); EVP_DigestFinal(&ctx, digest, &len); - memcpy(&addr_refid, digest, 4); + memcpy(&addr_refid, digest, sizeof(addr_refid)); return (addr_refid); } diff --git a/libntp/caljulian.c b/libntp/caljulian.c index 42b9a8ce3..3aca68b4c 100644 --- a/libntp/caljulian.c +++ b/libntp/caljulian.c @@ -20,11 +20,12 @@ void caljulian( - u_int32 ntp, - struct calendar *jt ) + u_int32 ntp, + struct calendar * jt + ) { - vint64 vlong; - ntpcal_split split; + vint64 vlong; + ntpcal_split split; NTP_INSIST(NULL != jt); diff --git a/libntp/humandate.c b/libntp/humandate.c index 008152263..359191152 100644 --- a/libntp/humandate.c +++ b/libntp/humandate.c @@ -1,8 +1,9 @@ /* - * humandate - convert an NTP (or the current) time to something readable + * humandate.c - convert an NTP (or the current) time to something readable */ #include #include + #include "ntp_fp.h" #include "ntp_unixtime.h" /* includes and */ #include "lib_strbuf.h" diff --git a/libntp/lib_strbuf.c b/libntp/lib_strbuf.c index bdb3ace00..1551b9f69 100644 --- a/libntp/lib_strbuf.c +++ b/libntp/lib_strbuf.c @@ -25,6 +25,8 @@ int lib_inited; void init_lib(void) { + if (lib_inited) + return; ipv4_works = (ISC_R_SUCCESS == isc_net_probeipv4()); ipv6_works = (ISC_R_SUCCESS == isc_net_probeipv6()); lib_inited = TRUE; diff --git a/libntp/machines.c b/libntp/machines.c index b31a9e150..9ff8d61e7 100644 --- a/libntp/machines.c +++ b/libntp/machines.c @@ -13,6 +13,7 @@ #include "ntp_stdlib.h" #include "ntp_unixtime.h" #include "lib_strbuf.h" +#include "ntp_debug.h" #ifdef HAVE_UNISTD_H #include @@ -431,14 +432,13 @@ ntp_set_tod( void *tzp ) { - static int tod; - int rc = -1; - int saved_errno = 0; + static int tod; + int rc; + int saved_errno; -#ifdef DEBUG - if (debug) - printf("In ntp_set_tod\n"); -#endif + DPRINTF(1, ("In ntp_set_tod\n")); + rc = -1; + saved_errno = 0; #ifdef HAVE_CLOCK_SETTIME if (rc && (SET_TOD_CLOCK_SETTIME == tod || !tod)) { @@ -451,12 +451,7 @@ ntp_set_tod( errno = 0; rc = clock_settime(CLOCK_REALTIME, &ts); saved_errno = errno; -#ifdef DEBUG - if (debug) { - printf("ntp_set_tod: clock_settime: %d: %s\n", - rc, strerror(saved_errno)); - } -#endif + DPRINTF(1, ("ntp_set_tod: clock_settime: %d %m\n", rc)); if (!tod && !rc) tod = SET_TOD_CLOCK_SETTIME; @@ -475,12 +470,7 @@ ntp_set_tod( errno = 0; rc = SETTIMEOFDAY(tvp, tzp); saved_errno = errno; -#ifdef DEBUG - if (debug) { - printf("ntp_set_tod: settimeofday: %d: %s\n", - rc, strerror(saved_errno)); - } -#endif + DPRINTF(1, ("ntp_set_tod: settimeofday: %d %m\n", rc)); if (!tod && !rc) tod = SET_TOD_SETTIMEOFDAY; } @@ -492,23 +482,15 @@ ntp_set_tod( errno = 0; rc = stime(&tp); /* lie as bad as SysVR4 */ saved_errno = errno; -#ifdef DEBUG - if (debug) { - printf("ntp_set_tod: stime: %d: %s\n", - rc, strerror(saved_errno)); - } -#endif + DPRINTF(1, ("ntp_set_tod: stime: %d %m\n", rc)); if (!tod && !rc) tod = SET_TOD_STIME; } #endif /* HAVE_STIME */ -#ifdef DEBUG - if (debug) { - printf("ntp_set_tod: Final result: %s: %d: %s\n", - set_tod_used[tod], rc, strerror(saved_errno)); - } -#endif + errno = saved_errno; /* for %m below */ + DPRINTF(1, ("ntp_set_tod: Final result: %s: %d %m\n", + set_tod_used[tod], rc)); /* * Say how we're setting the time of day */ diff --git a/libntp/msyslog.c b/libntp/msyslog.c index 6b3453632..67f7acd20 100644 --- a/libntp/msyslog.c +++ b/libntp/msyslog.c @@ -16,6 +16,7 @@ #include #include "ntp.h" +#include "ntp_debug.h" #include "ntp_string.h" #include "ntp_syslog.h" @@ -227,6 +228,68 @@ mvsnprintf( } +int +mvfprintf( + FILE * fp, + const char * fmt, + va_list ap + ) +{ + char nfmt[256]; + int errval; + int rc; + + /* + * Save the error value as soon as possible + */ +#ifdef SYS_WINNT + errval = GetLastError(); + if (NO_ERROR == errval) +#endif /* SYS_WINNT */ + errval = errno; + + format_errmsg(nfmt, sizeof(nfmt), fmt, errval); + rc = vfprintf(fp, nfmt, ap); + + return rc; +} + + +int +mfprintf( + FILE * fp, + const char * fmt, + ... + ) +{ + va_list ap; + int rc; + + va_start(ap, fmt); + rc = mvfprintf(fp, fmt, ap); + va_end(ap); + + return rc; +} + + +int +mprintf( + const char * fmt, + ... + ) +{ + va_list ap; + int rc; + + va_start(ap, fmt); + rc = mvfprintf(stderr, fmt, ap); + va_end(ap); + + return rc; +} + + int msnprintf( char * buf, @@ -261,3 +324,221 @@ msyslog( va_end(ap); addto_syslog(level, buf); } + + +/* + * Initialize the logging + * + * Called once per process, including forked children. + */ +void +init_logging( + const char * name, + u_long def_syslogmask, + const char * version_str, + int is_daemon + ) +{ + static int was_daemon; + const char * cp; + const char * pname; + + /* + * ntpd defaults to only logging sync-category events, when + * NLOG() is used to conditionalize. Other libntp clients + * leave it alone so that all NLOG() conditionals will fire. + * This presumes all bits lit in ntp_syslogmask can't be + * configured via logconfig and all lit is thereby a sentinel + * that ntp_syslogmask is still at its default from libntp, + * keeping in mind this function is called in forked children + * where it has already been called in the parent earlier. + */ + if (~(u_long)0 == ntp_syslogmask && 0 != def_syslogmask) + ntp_syslogmask = def_syslogmask; /* set more via logconfig */ + + /* + * Logging. This may actually work on the gizmo board. Find a name + * to log with by using the basename + */ + cp = strrchr(name, DIR_SEP); + if (NULL == cp) + pname = name; + else + pname = 1 + cp; /* skip DIR_SEP */ + progname = estrdup(pname); +#ifdef SYS_WINNT /* strip ".exe" */ + cp = strrchr(progname, '.'); + if (NULL != cp && !strcasecmp(cp, ".exe")) + progname[cp - progname] = '\0'; +#endif + +#if !defined(VMS) + + if (is_daemon) + was_daemon = TRUE; +# ifndef LOG_DAEMON + openlog(progname, LOG_PID); +# else /* LOG_DAEMON */ + +# ifndef LOG_NTP +# define LOG_NTP LOG_DAEMON +# endif + openlog(progname, LOG_PID | LOG_NDELAY, (was_daemon) + ? LOG_NTP + : 0); +# ifdef DEBUG + if (debug) + setlogmask(LOG_UPTO(LOG_DEBUG)); + else +# endif /* DEBUG */ + setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */ +# endif /* LOG_DAEMON */ +#endif /* !VMS */ + + if (NULL != version_str) + msyslog(LOG_NOTICE, "%s", version_str); +} + + +/* + * change_logfile() + * + * Used to change from syslog to a logfile, or from one logfile to + * another, and to reopen logfiles after forking. On systems where + * ntpd forks, deals with converting relative logfile paths to + * absolute (root-based) because we reopen logfiles after the current + * directory has changed. + */ +int +change_logfile( + const char * fname, + const char * version_str + ) +{ + FILE * new_file; + const char * log_fname; + char * abs_fname; +#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS) + char curdir[512]; + size_t cd_octets; + size_t octets; +#endif /* POSIX */ + + NTP_REQUIRE(fname != NULL); + log_fname = fname; + + /* + * In a forked child of a parent which is logging to a file + * instead of syslog, syslog_file will be NULL and both + * syslog_fname and syslog_abs_fname will be non-NULL. + * If we are given the same filename previously opened + * and it's still open, there's nothing to do here. + */ + if (syslog_file != NULL && syslog_fname != NULL && + (log_fname == syslog_fname || + 0 == strcmp(syslog_fname, log_fname))) + return 0; + + if (0 == strcmp(log_fname, "stderr")) { + new_file = stderr; + abs_fname = estrdup(log_fname); + } else if (0 == strcmp(log_fname, "stdout")) { + new_file = stdout; + abs_fname = estrdup(log_fname); + } else { + if (syslog_fname != NULL && + 0 == strcmp(log_fname, syslog_fname)) + log_fname = syslog_abs_fname; +#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS) + if (log_fname != syslog_abs_fname && + DIR_SEP != log_fname[0] && + 0 != strcmp(log_fname, "stderr") && + 0 != strcmp(log_fname, "stdout") && + NULL != getcwd(curdir, sizeof(curdir))) { + cd_octets = strlen(curdir); + /* trim any trailing '/' */ + if (cd_octets > 1 && + DIR_SEP == curdir[cd_octets - 1]) + cd_octets--; + octets = cd_octets; + octets += 1; /* separator '/' */ + octets += strlen(log_fname); + octets += 1; /* NUL terminator */ + abs_fname = emalloc(octets); + snprintf(abs_fname, octets, "%.*s%c%s", + (int)cd_octets, curdir, DIR_SEP, + log_fname); + } else +#endif + abs_fname = estrdup(log_fname); + DPRINTF(1, ("attempting to open log %s\n", abs_fname)); + new_file = fopen(abs_fname, "a"); + } + + if (NULL == new_file) { + free(abs_fname); + return -1; + } + + /* leave a pointer in the old log */ + if (syslogit || log_fname != syslog_abs_fname) + msyslog(LOG_NOTICE, "switching logging to file %s", + abs_fname); + + if (syslog_file != NULL && + syslog_file != stderr && syslog_file != stdout && + fileno(syslog_file) != fileno(new_file)) + fclose(syslog_file); + syslog_file = new_file; + if (log_fname != syslog_abs_fname) { + if (syslog_abs_fname != NULL && + syslog_abs_fname != syslog_fname) + free(syslog_abs_fname); + if (syslog_fname != NULL) + free(syslog_fname); + syslog_fname = estrdup(log_fname); + syslog_abs_fname = abs_fname; + } + syslogit = FALSE; + if (NULL != version_str) + msyslog(LOG_NOTICE, "%s", version_str); + + return 0; +} + + +/* + * setup_logfile() + * + * Redirect logging to a file if requested with -l/--logfile or via + * ntp.conf logfile directive. + * + * This routine is invoked three different times in the sequence of a + * typical daemon ntpd with DNS lookups to do. First it is invoked in + * the original ntpd process, then again in the daemon after closing + * all descriptors. In both of those cases, ntp.conf has not been + * processed, so only -l/--logfile will trigger logfile redirection in + * those invocations. Finally, if DNS names are resolved, the worker + * child invokes this routine after its fork and close of all + * descriptors. In this case, ntp.conf has been processed and any + * "logfile" directive needs to be honored in the child as well. + */ +void +setup_logfile( + const char * name, + const char * version_str + ) +{ + if (NULL == syslog_fname && NULL != name) { + if (-1 == change_logfile(name, version_str)) + msyslog(LOG_ERR, "Cannot open log file %s, %m", + name); + return ; + } + if (NULL == syslog_fname) + return; + + if (-1 == change_logfile(syslog_fname, version_str)) + msyslog(LOG_ERR, "Cannot reopen log file %s, %m", + syslog_fname); +} diff --git a/ntpd/ntp_intres.c b/libntp/ntp_intres.c similarity index 70% rename from ntpd/ntp_intres.c rename to libntp/ntp_intres.c index c493e3377..1c7cf5562 100644 --- a/ntpd/ntp_intres.c +++ b/libntp/ntp_intres.c @@ -28,6 +28,9 @@ * blocking child worker with the ntpd mainline. The threaded code * uses arrays of pointers to queue requests and responses. * + * The parent drives the process, including scheduling sleeps between + * retries. + * * Memory is managed differently for a child process, which mallocs * request buffers to read from the pipe into, whereas the threaded * code mallocs a copy of the request to hand off to the worker via @@ -89,14 +92,13 @@ # endif #endif -#include "ntp_stdlib.h" +#include "ntp.h" +#include "ntp_debug.h" #include "ntp_malloc.h" #include "ntp_syslog.h" -#include "ntpd.h" -#include "ntp_io.h" -#include "ntp_assert.h" #include "ntp_unixtime.h" #include "ntp_intres.h" +#include "intreswork.h" /* @@ -116,8 +118,10 @@ * is managed by the code which calls the *_complete routines. */ -typedef struct blocking_gai_req_tag { +/* === typedefs === */ +typedef struct blocking_gai_req_tag { /* marshalled args */ size_t octets; + u_int dns_idx; time_t scheduled; time_t earliest; struct addrinfo hints; @@ -131,6 +135,7 @@ typedef struct blocking_gai_req_tag { typedef struct blocking_gai_resp_tag { size_t octets; int retcode; + int retry; int gai_errno; /* for EAI_SYSTEM case */ int ai_count; /* @@ -141,6 +146,7 @@ typedef struct blocking_gai_resp_tag { typedef struct blocking_gni_req_tag { size_t octets; + u_int dns_idx; time_t scheduled; time_t earliest; int retry; @@ -156,6 +162,7 @@ typedef struct blocking_gni_resp_tag { size_t octets; int retcode; int gni_errno; /* for EAI_SYSTEM case */ + int retry; size_t hostoctets; size_t servoctets; /* @@ -164,22 +171,62 @@ typedef struct blocking_gni_resp_tag { */ } blocking_gni_resp; -static time_t next_dns_timeslot; -static time_t ignore_scheduled_before; +/* per-DNS-worker state in parent */ +typedef struct dnschild_ctx_tag { + u_int index; + time_t next_dns_timeslot; +} dnschild_ctx; + +/* per-DNS-worker state in worker */ +typedef struct dnsworker_ctx_tag { + blocking_child * c; + time_t ignore_scheduled_before; #ifdef HAVE_RES_INIT -static time_t next_res_init; + time_t next_res_init; #endif +} dnsworker_ctx; -static void scheduled_sleep(time_t, time_t); -static void manage_dns_retry_interval(time_t *, time_t *, int *); -static int should_retry_dns(int, int); -static void getaddrinfo_sometime_complete(blocking_work_req, void *, - size_t, void *); -static void getnameinfo_sometime_complete(blocking_work_req, void *, - size_t, void *); +/* === variables === */ +dnschild_ctx ** dnschild_contexts; /* parent */ +u_int dnschild_contexts_alloc; +dnsworker_ctx ** dnsworker_contexts; /* child */ +u_int dnsworker_contexts_alloc; +#ifdef HAVE_RES_INIT +static time_t next_res_init; +#endif + +/* === forward declarations === */ +static u_int reserve_dnschild_ctx(void); +static u_int get_dnschild_ctx(void); +static void alloc_dnsworker_context(u_int); +/* static void free_dnsworker_context(u_int); */ +static dnsworker_ctx * get_worker_context(blocking_child *, u_int); +static void scheduled_sleep(time_t, time_t, + dnsworker_ctx *); +static void manage_dns_retry_interval(time_t *, time_t *, + int *, + time_t *); +static int should_retry_dns(int, int); +#ifdef HAVE_RES_INIT +static void reload_resolv_conf(dnsworker_ctx *); +#else +# define reload_resolv_conf(wc) \ + do { \ + (void)(wc); \ + } while (FALSE) +#endif +static void getaddrinfo_sometime_complete(blocking_work_req, + void *, size_t, + void *); +static void getnameinfo_sometime_complete(blocking_work_req, + void *, size_t, + void *); + + +/* === functions === */ /* * getaddrinfo_sometime - uses blocking child to call getaddrinfo then * invokes provided callback completion function. @@ -195,6 +242,8 @@ getaddrinfo_sometime( ) { blocking_gai_req * gai_req; + u_int idx; + dnschild_ctx * child_ctx; size_t req_size; size_t nodesize; size_t servsize; @@ -208,6 +257,9 @@ getaddrinfo_sometime( NTP_REQUIRE(NULL == hints->ai_next); } + idx = get_dnschild_ctx(); + child_ctx = dnschild_contexts[idx]; + nodesize = strlen(node) + 1; servsize = strlen(service) + 1; req_size = sizeof(*gai_req) + nodesize + servsize; @@ -215,10 +267,11 @@ getaddrinfo_sometime( gai_req = emalloc_zero(req_size); gai_req->octets = req_size; + gai_req->dns_idx = idx; now = time(NULL); - next_dns_timeslot = max(now, next_dns_timeslot); gai_req->scheduled = now; - gai_req->earliest = next_dns_timeslot; + gai_req->earliest = max(now, child_ctx->next_dns_timeslot); + child_ctx->next_dns_timeslot = gai_req->earliest; if (hints != NULL) gai_req->hints = *hints; gai_req->retry = retry; @@ -248,10 +301,12 @@ getaddrinfo_sometime( int blocking_getaddrinfo( + blocking_child * c, blocking_pipe_header * req ) { blocking_gai_req * gai_req; + dnsworker_ctx * worker_ctx; blocking_pipe_header * resp; blocking_gai_resp * gai_resp; char * node; @@ -269,50 +324,39 @@ blocking_getaddrinfo( node = (char *)gai_req + sizeof(*gai_req); service = node + gai_req->nodesize; - scheduled_sleep(gai_req->scheduled, gai_req->earliest); - -#ifdef HAVE_RES_INIT - /* - * This is ad-hoc. Reload /etc/resolv.conf once per minute - * to pick up on changes from the DHCP client. [Bug 1226] - */ - time_now = time(NULL); - if (next_res_init <= time_now) { - if (next_res_init) - res_init(); - next_res_init = time_now + 60; - } -#endif + worker_ctx = get_worker_context(c, gai_req->dns_idx); + scheduled_sleep(gai_req->scheduled, gai_req->earliest, + worker_ctx); + reload_resolv_conf(worker_ctx); /* * Take a shot at the final size, better to overestimate * at first and then realloc to a smaller size. */ - resp = emalloc(sizeof(*resp) + sizeof(*gai_resp) - + 16 * (sizeof(struct addrinfo) - + sizeof(sockaddr_u)) - + 256); + resp_octets = sizeof(*resp) + sizeof(*gai_resp) + + 16 * (sizeof(struct addrinfo) + + sizeof(sockaddr_u)) + + 256; + resp = emalloc_zero(resp_octets); gai_resp = (void *)(resp + 1); DPRINTF(2, ("blocking_getaddrinfo given node %s serv %s fam %d flags %x\n", node, service, gai_req->hints.ai_family, gai_req->hints.ai_flags)); - +#ifdef DEBUG + if (debug >= 2) + fflush(stdout); +#endif ai_res = NULL; - gai_resp->retcode = getaddrinfo(node, service, &gai_req->hints, &ai_res); - - switch (gai_resp->retcode) { + gai_resp->retcode = getaddrinfo(node, service, &gai_req->hints, + &ai_res); + gai_resp->retry = gai_req->retry; #ifdef EAI_SYSTEM - case EAI_SYSTEM: + if (EAI_SYSTEM == gai_resp->retcode) gai_resp->gai_errno = errno; - break; #endif - default: - gai_resp->gai_errno = 0; - } - - gai_resp->ai_count = canons_octets = 0; + canons_octets = 0; if (!gai_resp->retcode) { ai = ai_res; @@ -329,12 +373,15 @@ blocking_getaddrinfo( * the way scheduled_sleep() does when its worker_sleep() * is interrupted. */ - if (gai_req->retry > INITIAL_DNS_RETRY) { + if (gai_resp->retry > INITIAL_DNS_RETRY) { time_now = time(NULL); - ignore_scheduled_before = time_now; - next_dns_timeslot = time_now; + worker_ctx->ignore_scheduled_before = time_now; DPRINTF(1, ("DNS success after retry, ignoring sleeps scheduled before now (%s)", humantime(time_now))); +#ifdef DEBUG + if (debug >= 1) + fflush(stdout); +#endif } } @@ -358,7 +405,6 @@ blocking_getaddrinfo( canons_octets = 0; if (!gai_resp->retcode) { - ai = ai_res; while (NULL != ai) { memcpy(cp, ai, sizeof(*ai)); @@ -400,10 +446,11 @@ blocking_getaddrinfo( /* * make sure our walk and earlier calc match */ - NTP_INSIST((size_t)(cp - (char *)resp) == resp_octets); + DEBUG_INSIST((size_t)(cp - (char *)resp) == resp_octets); + freeaddrinfo(ai_res); - if (queue_blocking_response(resp, resp_octets, req)) { - DPRINTF(1, ("blocking_getaddrinfo unable to queue response")); + if (queue_blocking_response(c, resp, resp_octets, req)) { + msyslog(LOG_ERR, "blocking_getaddrinfo can not queue response"); return -1; } @@ -419,30 +466,46 @@ getaddrinfo_sometime_complete( void * resp ) { - blocking_gai_req * gai_req; - blocking_gai_resp * gai_resp; - struct addrinfo * ai; - struct addrinfo * next_ai; - sockaddr_u * psau; - char * node; - char * service; - char * canon_start; - int again; - int af; - const char * fam_spec; - int i; + blocking_gai_req * gai_req; + blocking_gai_resp * gai_resp; + dnschild_ctx * child_ctx; + struct addrinfo * ai; + struct addrinfo * next_ai; + sockaddr_u * psau; + char * node; + char * service; + char * canon_start; + time_t time_now; + int again; + int af; + const char * fam_spec; + int i; gai_req = context; gai_resp = resp; - NTP_REQUIRE(BLOCKING_GETADDRINFO == rtype); - NTP_REQUIRE(respsize == gai_resp->octets); + DEBUG_REQUIRE(BLOCKING_GETADDRINFO == rtype); + DEBUG_REQUIRE(respsize == gai_resp->octets); node = (char *)gai_req + sizeof(*gai_req); service = node + gai_req->nodesize; - if (gai_resp->retcode) { - again = should_retry_dns(gai_resp->retcode, gai_resp->gai_errno); + child_ctx = dnschild_contexts[gai_req->dns_idx]; + + if (0 == gai_resp->retcode) { + /* + * If this query succeeded only after retrying, DNS may have + * just become responsive. + */ + if (gai_resp->retry > INITIAL_DNS_RETRY) { + time_now = time(NULL); + child_ctx->next_dns_timeslot = time_now; + DPRINTF(1, ("DNS success after retry, %u next_dns_timeslot reset (%s)", + gai_req->dns_idx, humantime(time_now))); + } + } else { + again = should_retry_dns(gai_resp->retcode, + gai_resp->gai_errno); /* * exponential backoff of DNS retries to 64s */ @@ -457,13 +520,13 @@ getaddrinfo_sometime_complete( ? " (A)" : ""; #ifdef EAI_SYSTEM - if (EAI_SYSTEM == gai_resp->retcode) + if (EAI_SYSTEM == gai_resp->retcode) { + errno = gai_resp->gai_errno; msyslog(LOG_INFO, - "retrying DNS %s%s: EAI_SYSTEM %s (%d)", + "retrying DNS %s%s: EAI_SYSTEM %d: %m", node, fam_spec, - strerror(gai_resp->gai_errno), gai_resp->gai_errno); - else + } else #endif msyslog(LOG_INFO, "retrying DNS %s%s: %s (%d)", @@ -472,7 +535,8 @@ getaddrinfo_sometime_complete( gai_resp->retcode); } manage_dns_retry_interval(&gai_req->scheduled, - &gai_req->earliest, &gai_req->retry); + &gai_req->earliest, &gai_req->retry, + &child_ctx->next_dns_timeslot); if (!queue_blocking_request( BLOCKING_GETADDRINFO, gai_req, @@ -481,7 +545,9 @@ getaddrinfo_sometime_complete( gai_req)) return; else - msyslog(LOG_ERR, "unable to retry hostname %s", node); + msyslog(LOG_ERR, + "unable to retry hostname %s", + node); } } @@ -516,7 +582,7 @@ getaddrinfo_sometime_complete( &gai_req->hints, ai); free(gai_req); - /* gai_resp is part of block freed by process_blocking_response() */ + /* gai_resp is part of block freed by process_blocking_resp() */ } @@ -568,18 +634,24 @@ getnameinfo_sometime( ) { blocking_gni_req * gni_req; + u_int idx; + dnschild_ctx * child_ctx; time_t time_now; NTP_REQUIRE(hostoctets); NTP_REQUIRE(hostoctets + servoctets < 1024); + idx = get_dnschild_ctx(); + child_ctx = dnschild_contexts[idx]; + gni_req = emalloc_zero(sizeof(*gni_req)); gni_req->octets = sizeof(*gni_req); + gni_req->dns_idx = idx; time_now = time(NULL); - next_dns_timeslot = max(time_now, next_dns_timeslot); gni_req->scheduled = time_now; - gni_req->earliest = next_dns_timeslot; + gni_req->earliest = max(time_now, child_ctx->next_dns_timeslot); + child_ctx->next_dns_timeslot = gni_req->earliest; memcpy(&gni_req->socku, psau, SOCKLEN(psau)); gni_req->hostoctets = hostoctets; gni_req->servoctets = servoctets; @@ -606,10 +678,12 @@ getnameinfo_sometime( int blocking_getnameinfo( + blocking_child * c, blocking_pipe_header * req ) { blocking_gni_req * gni_req; + dnsworker_ctx * worker_ctx; blocking_pipe_header * resp; blocking_gni_resp * gni_resp; size_t octets; @@ -644,20 +718,10 @@ blocking_getnameinfo( #endif service = host + gni_req->hostoctets; - scheduled_sleep(gni_req->scheduled, gni_req->earliest); - -#ifdef HAVE_RES_INIT - /* - * This is ad-hoc. Reload /etc/resolv.conf once per minute - * to pick up on changes from the DHCP client. [Bug 1226] - */ - time_now = time(NULL); - if (next_res_init <= time_now) { - if (next_res_init) - res_init(); - next_res_init = time_now + 60; - } -#endif + worker_ctx = get_worker_context(c, gni_req->dns_idx); + scheduled_sleep(gni_req->scheduled, gni_req->earliest, + worker_ctx); + reload_resolv_conf(worker_ctx); /* * Take a shot at the final size, better to overestimate @@ -665,7 +729,7 @@ blocking_getnameinfo( */ resp_octets = sizeof(*resp) + sizeof(*gni_resp) + octets; - resp = emalloc(resp_octets); + resp = emalloc_zero(resp_octets); gni_resp = (void *)((char *)resp + sizeof(*resp)); DPRINTF(2, ("blocking_getnameinfo given addr %s flags 0x%x hostlen %lu servlen %lu\n", @@ -679,16 +743,11 @@ blocking_getnameinfo( service, gni_req->servoctets, gni_req->flags); - - switch (gni_resp->retcode) { + gni_resp->retry = gni_req->retry; #ifdef EAI_SYSTEM - case EAI_SYSTEM: + if (EAI_SYSTEM == gni_resp->retcode) gni_resp->gni_errno = errno; - break; #endif - default: - gni_resp->gni_errno = 0; - } if (gni_resp->retcode) { gni_resp->hostoctets = 0; @@ -705,8 +764,7 @@ blocking_getnameinfo( */ if (gni_req->retry > INITIAL_DNS_RETRY) { time_now = time(NULL); - ignore_scheduled_before = time_now; - next_dns_timeslot = time_now; + worker_ctx->ignore_scheduled_before = time_now; DPRINTF(1, ("DNS success after retrying, ignoring sleeps scheduled before now (%s)", humantime(time_now))); } @@ -736,7 +794,7 @@ blocking_getnameinfo( NTP_INSIST((size_t)(cp - (char *)resp) == resp_octets); NTP_INSIST(resp_octets - sizeof(*resp) == gni_resp->octets); - rc = queue_blocking_response(resp, resp_octets, req); + rc = queue_blocking_response(c, resp, resp_octets, req); if (rc) msyslog(LOG_ERR, "blocking_getnameinfo unable to queue response"); #ifndef HAVE_ALLOCA @@ -756,24 +814,40 @@ getnameinfo_sometime_complete( { blocking_gni_req * gni_req; blocking_gni_resp * gni_resp; + dnschild_ctx * child_ctx; char * host; char * service; + time_t time_now; int again; gni_req = context; gni_resp = resp; - NTP_REQUIRE(BLOCKING_GETNAMEINFO == rtype); - NTP_REQUIRE(respsize == gni_resp->octets); + DEBUG_REQUIRE(BLOCKING_GETNAMEINFO == rtype); + DEBUG_REQUIRE(respsize == gni_resp->octets); - if (gni_resp->retcode) { + child_ctx = dnschild_contexts[gni_req->dns_idx]; + + if (0 == gni_resp->retcode) { + /* + * If this query succeeded only after retrying, DNS may have + * just become responsive. + */ + if (gni_resp->retry > INITIAL_DNS_RETRY) { + time_now = time(NULL); + child_ctx->next_dns_timeslot = time_now; + DPRINTF(1, ("DNS success after retry, %u next_dns_timeslot reset (%s)", + gni_req->dns_idx, humantime(time_now))); + } + } else { again = should_retry_dns(gni_resp->retcode, gni_resp->gni_errno); /* * exponential backoff of DNS retries to 64s */ if (gni_req->retry) manage_dns_retry_interval(&gni_req->scheduled, - &gni_req->earliest, &gni_req->retry); + &gni_req->earliest, &gni_req->retry, + &child_ctx->next_dns_timeslot); if (gni_req->retry && again) { if (!queue_blocking_request( @@ -803,7 +877,7 @@ getnameinfo_sometime_complete( service, gni_req->context); free(gni_req); - /* gni_resp is part of block freed by process_blocking_response() */ + /* gni_resp is part of block freed by process_blocking_resp() */ } @@ -820,18 +894,137 @@ void gni_test_callback(int rescode, int gni_errno, sockaddr_u *psau, int flags, #endif /* TEST_BLOCKING_WORKER */ +#ifdef HAVE_RES_INIT +static void +reload_resolv_conf( + dnsworker_ctx * worker_ctx + ) +{ + time_t time_now; + + /* + * This is ad-hoc. Reload /etc/resolv.conf once per minute + * to pick up on changes from the DHCP client. [Bug 1226] + * When using threads for the workers, this needs to happen + * only once per minute process-wide. + */ + time_now = time(NULL); +# ifdef WORK_THREAD + worker_ctx->next_res_init = next_res_init; +# endif + if (worker_ctx->next_res_init <= time_now) { + if (worker_ctx->next_res_init != 0) + res_init(); + worker_ctx->next_res_init = time_now + 60; +# ifdef WORK_THREAD + next_res_init = worker_ctx->next_res_init; +# endif + } +} +#endif /* HAVE_RES_INIT */ + + +static u_int +reserve_dnschild_ctx(void) +{ + const size_t ps = sizeof(dnschild_contexts[0]); + const size_t cs = sizeof(*dnschild_contexts[0]); + u_int c; + u_int new_alloc; + size_t octets; + size_t new_octets; + + c = 0; + while (TRUE) { + for ( ; c < dnschild_contexts_alloc; c++) { + if (NULL == dnschild_contexts[c]) { + dnschild_contexts[c] = emalloc_zero(cs); + + return c; + } + } + new_alloc = dnschild_contexts_alloc + 20; + new_octets = new_alloc * ps; + octets = dnschild_contexts_alloc * ps; + dnschild_contexts = erealloc_zero(dnschild_contexts, + new_octets, octets); + dnschild_contexts_alloc = new_alloc; + } +} + + +static u_int +get_dnschild_ctx(void) +{ + static u_int shared_ctx = UINT_MAX; + + if (worker_per_query) + return reserve_dnschild_ctx(); + + if (UINT_MAX == shared_ctx) + shared_ctx = reserve_dnschild_ctx(); + + return shared_ctx; +} + + +static void +alloc_dnsworker_context( + u_int idx + ) +{ + const size_t worker_context_sz = sizeof(*dnsworker_contexts[0]); + + REQUIRE(NULL == dnsworker_contexts[idx]); + dnsworker_contexts[idx] = emalloc_zero(worker_context_sz); +} + + +static dnsworker_ctx * +get_worker_context( + blocking_child * c, + u_int idx + ) +{ + static size_t ps = sizeof(dnsworker_contexts[0]); + u_int min_new_alloc; + u_int new_alloc; + size_t octets; + size_t new_octets; + + if (dnsworker_contexts_alloc <= idx) { + min_new_alloc = 1 + idx; + /* round new_alloc up to nearest multiple of 4 */ + new_alloc = (min_new_alloc + 4) & ~(4 - 1); + new_octets = new_alloc * ps; + octets = dnsworker_contexts_alloc * ps; + dnsworker_contexts = erealloc_zero(dnsworker_contexts, + new_octets, octets); + dnsworker_contexts_alloc = new_alloc; + } + + if (NULL == dnsworker_contexts[idx]) + alloc_dnsworker_context(idx); + ZERO(*dnsworker_contexts[idx]); + dnsworker_contexts[idx]->c = c; + + return dnsworker_contexts[idx]; +} + + static void scheduled_sleep( - time_t scheduled, - time_t earliest + time_t scheduled, + time_t earliest, + dnsworker_ctx * worker_ctx ) { time_t now; - if (scheduled < ignore_scheduled_before) { + if (scheduled < worker_ctx->ignore_scheduled_before) { DPRINTF(1, ("ignoring sleep until %s scheduled at %s (before %s)\n", humantime(earliest), humantime(scheduled), - humantime(ignore_scheduled_before))); + humantime(worker_ctx->ignore_scheduled_before))); return; } @@ -840,18 +1033,18 @@ scheduled_sleep( if (now < earliest) { DPRINTF(1, ("sleep until %s scheduled at %s (>= %s)\n", humantime(earliest), humantime(scheduled), - humantime(ignore_scheduled_before))); - if (-1 == worker_sleep(earliest - now)) { + humantime(worker_ctx->ignore_scheduled_before))); + if (-1 == worker_sleep(worker_ctx->c, earliest - now)) { /* our sleep was interrupted */ now = time(NULL); - ignore_scheduled_before = now; - next_dns_timeslot = now; + worker_ctx->ignore_scheduled_before = now; #ifdef HAVE_RES_INIT - next_res_init = now + 60; + worker_ctx->next_res_init = now + 60; + next_res_init = worker_ctx->next_res_init; res_init(); #endif DPRINTF(1, ("sleep interrupted by daemon, ignoring sleeps scheduled before now (%s)\n", - humantime(ignore_scheduled_before))); + humantime(worker_ctx->ignore_scheduled_before))); } } } @@ -866,7 +1059,8 @@ static void manage_dns_retry_interval( time_t * pscheduled, time_t * pwhen, - int * pretry + int * pretry, + time_t * pnext_timeslot ) { time_t now; @@ -875,8 +1069,8 @@ manage_dns_retry_interval( now = time(NULL); retry = *pretry; - when = max(now + retry, next_dns_timeslot); - next_dns_timeslot = when; + when = max(now + retry, *pnext_timeslot); + *pnext_timeslot = when; retry = min(64, retry << 1); *pscheduled = now; @@ -897,6 +1091,9 @@ should_retry_dns( { static int eai_again_seen; int again; +#if defined (EAI_SYSTEM) && defined(DEBUG) + char msg[256]; +#endif /* * If the resolver failed, see if the failure is @@ -930,8 +1127,11 @@ should_retry_dns( * this matches existing behavior. */ again = 1; +# ifdef DEBUG + errno_to_str(res_errno, msg, sizeof(msg)); DPRINTF(1, ("intres: EAI_SYSTEM errno %d (%s) means try again, right?\n", - res_errno, strerror(res_errno))); + res_errno, msg)); +# endif break; #endif } diff --git a/libntp/ntp_libopts.c b/libntp/ntp_libopts.c index f15597001..7c1936821 100644 --- a/libntp/ntp_libopts.c +++ b/libntp/ntp_libopts.c @@ -15,6 +15,15 @@ extern const char *Version; /* version.c for each program */ +typedef struct options_fv_tag { + u_char padding[offsetof(tOptions, pzFullVersion)]; + const char * pzFullVersion; +} options_fv; + +typedef union options_const_trick_tag { + tOptions orig; /* for alignment */ + options_fv fv; +} options_const_trick; /* * ntpOptionProcess() is a clone of libopts' optionProcess which @@ -28,26 +37,23 @@ ntpOptionProcess( char ** argv ) { - char * pchOpts; - char ** ppzFullVersion; - char * pzNewFV; - char * pzAutogenFV; - size_t octets; - int rc; + options_const_trick * pOpts_fv; + const char * pzAutogenFV; + char * pzNewFV; + size_t octets; + int rc; - pchOpts = (void *)pOpts; - ppzFullVersion = (char **)(pchOpts + offsetof(tOptions, - pzFullVersion)); - pzAutogenFV = *ppzFullVersion; + pOpts_fv = (void *)pOpts; + pzAutogenFV = pOpts_fv->fv.pzFullVersion; octets = strlen(pzAutogenFV) + 1 + /* '\n' */ strlen(Version) + 1; /* '\0' */ pzNewFV = emalloc(octets); snprintf(pzNewFV, octets, "%s\n%s", pzAutogenFV, Version); - *ppzFullVersion = pzNewFV; + pOpts_fv->fv.pzFullVersion = pzNewFV; rc = optionProcess(pOpts, argc, argv); - *ppzFullVersion = pzAutogenFV; + pOpts_fv->fv.pzFullVersion = pzAutogenFV; free(pzNewFV); return rc; diff --git a/libntp/ntp_lineedit.c b/libntp/ntp_lineedit.c index ed579c986..c5aad3108 100644 --- a/libntp/ntp_lineedit.c +++ b/libntp/ntp_lineedit.c @@ -93,8 +93,7 @@ ntp_readline_init( if (NULL == ntp_hist) { - fprintf(stderr, "history_init(): %s\n", - strerror(errno)); + mfprintf(stderr, "history_init(): %m\n"); fflush(stderr); el_end(ntp_el); diff --git a/libntp/ntp_random.c b/libntp/ntp_random.c index c982a0d0a..28deea467 100644 --- a/libntp/ntp_random.c +++ b/libntp/ntp_random.c @@ -140,15 +140,8 @@ static char sccsid[] = "@(#)random.c 8.2 (Berkeley) 5/19/95"; #define DEG_4 63 #define SEP_4 1 -/* - * Array versions of the above information to make code run faster -- - * relies on fact that TYPE_i == i. - */ #define MAX_TYPES 5 /* max number of types above */ -static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; -static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; - /* * Initially, everything is set up as if from: * @@ -307,6 +300,24 @@ ntp_srandomdev( void ) } #endif + +/* + * ntp_initstate() and ntp_setstate() are unused in our codebase and + * trigger warnings due to casting to a more-strictly-aligned pointer + * on alignment-sensitive platforms. #ifdef them away to save noise, + * build time, and binary space, but retain the code in case we find a + * use. + */ +#ifdef COMPILE_UNUSED_FUNCTIONS +/* + * Array versions of the above information to make code run faster -- + * relies on fact that TYPE_i == i. + */ +#define MAX_TYPES 5 /* max number of types above */ + +static long degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }; +static long seps [MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 }; + /* * initstate: * @@ -435,6 +446,8 @@ ntp_setstate( end_ptr = &state[rand_deg]; /* set end_ptr too */ return(ostate); } +#endif /* COMPILE_UNUSED_FUNCTIONS */ + /* * random: diff --git a/libntp/ntp_rfc2553.c b/libntp/ntp_rfc2553.c index f5fd9b410..9c37aafa2 100644 --- a/libntp/ntp_rfc2553.c +++ b/libntp/ntp_rfc2553.c @@ -106,6 +106,45 @@ * The rest of ntp_rfc2553.c is conditioned on ISC_PLATFORM_HAVEIPV6 * not being defined, copy_addrinfo_list() is an exception. */ +struct addrinfo * +copy_addrinfo_impl( + const struct addrinfo * ai_src +#ifdef EREALLOC_CALLSITE + , + const char * caller_file, + int caller_line +#endif + ) +{ + struct addrinfo * dst; + size_t octets; + size_t canons_octets; + sockaddr_u * psau; + char * pcanon; + + octets = sizeof(*ai_src) + sizeof(*psau); + if (NULL != ai_src->ai_canonname) + canons_octets = 1 + strlen(ai_src->ai_canonname); + else + canons_octets = 0; + octets += canons_octets; + dst = erealloczsite(NULL, octets, 0, TRUE, caller_file, + caller_line); + psau = (void *)(dst + 1); + pcanon = (void *)(psau + 1); + *dst = *ai_src; + REQUIRE(ai_src->ai_addrlen <= sizeof(sockaddr_u)); + memcpy(psau, ai_src->ai_addr, ai_src->ai_addrlen); + dst->ai_addr = &psau->sa; + if (NULL != ai_src->ai_canonname) { + dst->ai_canonname = pcanon; + memcpy(pcanon, ai_src->ai_canonname, canons_octets); + } + + return dst; +} + + struct addrinfo * copy_addrinfo_list_impl( const struct addrinfo * src @@ -146,7 +185,7 @@ copy_addrinfo_list_impl( for (ai_src = src; NULL != ai_src; ai_src = ai_src->ai_next) { *ai_cpy = *ai_src; - NTP_REQUIRE(ai_src->ai_addrlen <= sizeof(sockaddr_u)); + REQUIRE(ai_src->ai_addrlen <= sizeof(sockaddr_u)); memcpy(psau, ai_src->ai_addr, ai_src->ai_addrlen); ai_cpy->ai_addr = &psau->sa; ++psau; diff --git a/libntp/ntp_worker.c b/libntp/ntp_worker.c new file mode 100644 index 000000000..bb1cb87e4 --- /dev/null +++ b/libntp/ntp_worker.c @@ -0,0 +1,340 @@ +/* + * ntp_worker.c + */ +#include +#include "ntp_workimpl.h" + +#ifdef WORKER + +#include +#include +#include + +#include "iosignal.h" +#include "ntp_stdlib.h" +#include "ntp_malloc.h" +#include "ntp_syslog.h" +#include "ntpd.h" +#include "ntp_io.h" +#include "ntp_assert.h" +#include "ntp_unixtime.h" +#include "intreswork.h" + + +#define CHILD_MAX_IDLE (3 * 60) /* seconds, idle worker limit */ + +blocking_child ** blocking_children; +size_t blocking_children_alloc; +int worker_per_query; /* boolean */ +int intres_req_pending; + + +#ifndef HAVE_IO_COMPLETION_PORT +/* + * pipe_socketpair() + * + * Provides an AF_UNIX socketpair on systems which have them, otherwise + * pair of unidirectional pipes. + */ +int +pipe_socketpair( + int caller_fds[2], + int * is_pipe + ) +{ + int rc; + int fds[2]; + int called_pipe; + +#ifdef HAVE_SOCKETPAIR + rc = socketpair(AF_UNIX, SOCK_STREAM, 0, &fds[0]); +#else + rc = -1; +#endif + + if (-1 == rc) { + rc = pipe(&fds[0]); + called_pipe = TRUE; + } else { + called_pipe = FALSE; + } + + if (-1 == rc) + return rc; + + caller_fds[0] = fds[0]; + caller_fds[1] = fds[1]; + if (is_pipe != NULL) + *is_pipe = called_pipe; + + return 0; +} + + +/* + * close_all_except() + * + * Close all file descriptors except the given keep_fd. + */ +void +close_all_except( + int keep_fd + ) +{ + int fd; + + for (fd = 0; fd < keep_fd; fd++) + close(fd); + + close_all_beyond(keep_fd); +} + + +/* + * close_all_beyond() + * + * Close all file descriptors after the given keep_fd, which is the + * highest fd to keep open. + */ +void +close_all_beyond( + int keep_fd + ) +{ +# ifdef HAVE_CLOSEFROM + closefrom(keep_fd + 1); +# elif defined(F_CLOSEM) + /* + * From 'Writing Reliable AIX Daemons,' SG24-4946-00, + * by Eric Agar (saves us from doing 32767 system + * calls) + */ + if (fcntl(keep_fd + 1, F_CLOSEM, 0) == -1) + msyslog(LOG_ERR, "F_CLOSEM(%d): %m", keep_fd + 1); +# else /* !HAVE_CLOSEFROM && !F_CLOSEM follows */ + int fd; + int max_fd; + + max_fd = GETDTABLESIZE(); + for (fd = keep_fd + 1; fd < max_fd; fd++) + close(fd); +# endif /* !HAVE_CLOSEFROM && !F_CLOSEM */ +} +#endif /* HAVE_IO_COMPLETION_PORT */ + + +u_int +available_blocking_child_slot(void) +{ + const size_t each = sizeof(blocking_children[0]); + u_int slot; + size_t prev_alloc; + size_t new_alloc; + size_t prev_octets; + size_t octets; + + for (slot = 0; slot < blocking_children_alloc; slot++) { + if (NULL == blocking_children[slot]) + return slot; + if (blocking_children[slot]->reusable) { + blocking_children[slot]->reusable = FALSE; + return slot; + } + } + + prev_alloc = blocking_children_alloc; + prev_octets = prev_alloc * each; + new_alloc = blocking_children_alloc + 4; + octets = new_alloc * each; + blocking_children = erealloc_zero(blocking_children, octets, + prev_octets); + blocking_children_alloc = new_alloc; + + return prev_alloc; +} + + +int +queue_blocking_request( + blocking_work_req rtype, + void * req, + size_t reqsize, + blocking_work_callback done_func, + void * context + ) +{ + static u_int intres_slot = UINT_MAX; + u_int child_slot; + blocking_child * c; + blocking_pipe_header req_hdr; + + req_hdr.octets = sizeof(req_hdr) + reqsize; + req_hdr.magic_sig = BLOCKING_REQ_MAGIC; + req_hdr.rtype = rtype; + req_hdr.done_func = done_func; + req_hdr.context = context; + + child_slot = UINT_MAX; + if (worker_per_query || UINT_MAX == intres_slot || + blocking_children[intres_slot]->reusable) + child_slot = available_blocking_child_slot(); + if (!worker_per_query) { + if (UINT_MAX == intres_slot) + intres_slot = child_slot; + else + child_slot = intres_slot; + if (0 == intres_req_pending) + intres_timeout_req(0); + } + intres_req_pending++; + INSIST(UINT_MAX != child_slot); + c = blocking_children[child_slot]; + if (NULL == c) { + c = emalloc_zero(sizeof(*c)); +#ifdef WORK_FORK + c->req_read_pipe = -1; + c->req_write_pipe = -1; +#endif +#ifdef WORK_PIPE + c->resp_read_pipe = -1; + c->resp_write_pipe = -1; +#endif + blocking_children[child_slot] = c; + } + req_hdr.child_idx = child_slot; + + return send_blocking_req_internal(c, &req_hdr, req); +} + + +int queue_blocking_response( + blocking_child * c, + blocking_pipe_header * resp, + size_t respsize, + const blocking_pipe_header * req + ) +{ + resp->octets = respsize; + resp->magic_sig = BLOCKING_RESP_MAGIC; + resp->rtype = req->rtype; + resp->context = req->context; + resp->done_func = req->done_func; + + return send_blocking_resp_internal(c, resp); +} + + +void +process_blocking_resp( + blocking_child * c + ) +{ + blocking_pipe_header * resp; + void * data; + + /* + * On Windows send_blocking_resp_internal() may signal the + * blocking_response_ready event multiple times while we're + * processing a response, so always consume all available + * responses before returning to test the event again. + */ +#ifdef WORK_THREAD + do { +#endif + resp = receive_blocking_resp_internal(c); + if (NULL != resp) { + DEBUG_REQUIRE(BLOCKING_RESP_MAGIC == + resp->magic_sig); + data = (char *)resp + sizeof(*resp); + intres_req_pending--; + (*resp->done_func)(resp->rtype, resp->context, + resp->octets - sizeof(*resp), + data); + free(resp); + } +#ifdef WORK_THREAD + } while (NULL != resp); +#endif + if (!worker_per_query && 0 == intres_req_pending) + intres_timeout_req(CHILD_MAX_IDLE); + else if (worker_per_query) + req_child_exit(c); +} + + +/* + * blocking_child_common runs as a forked child or a thread + */ +int +blocking_child_common( + blocking_child *c + ) +{ + int say_bye; + blocking_pipe_header *req; + + say_bye = FALSE; + while (!say_bye) { + req = receive_blocking_req_internal(c); + if (NULL == req) { + say_bye = TRUE; + break; + } + + DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == req->magic_sig); + + switch (req->rtype) { + case BLOCKING_GETADDRINFO: + if (blocking_getaddrinfo(c, req)) + say_bye = TRUE; + break; + + case BLOCKING_GETNAMEINFO: + if (blocking_getnameinfo(c, req)) + say_bye = TRUE; + break; + + default: + msyslog(LOG_ERR, "unknown req %d to blocking worker", req->rtype); + say_bye = TRUE; + } + + free(req); + } + + return 0; +} + + +/* + * worker_idle_timer_fired() + * + * The parent starts this timer when the last pending response has been + * received from the child, making it idle, and clears the timer when a + * request is dispatched to the child. Once the timer expires, the + * child is sent packing. + * + * This is called when worker_idle_timer is nonzero and less than or + * equal to current_time. + */ +void +worker_idle_timer_fired(void) +{ + u_int idx; + blocking_child * c; + + DEBUG_REQUIRE(0 == intres_req_pending); + + intres_timeout_req(0); + for (idx = 0; idx < blocking_children_alloc; idx++) { + c = blocking_children[idx]; + if (NULL == c) + continue; + req_child_exit(c); + } +} + + +#else /* !WORKER follows */ +int ntp_worker_nonempty_compilation_unit; +#endif diff --git a/libntp/socket.c b/libntp/socket.c index cedf5e8b2..957852079 100644 --- a/libntp/socket.c +++ b/libntp/socket.c @@ -9,9 +9,9 @@ #include #include "ntp.h" -#include "ntp_types.h" -#include "ntp_net.h" #include "ntp_io.h" +#include "ntp_net.h" +#include "ntp_debug.h" /* * Windows C runtime ioctl() can't deal properly with sockets, @@ -100,11 +100,9 @@ move_fd( if (socket_boundary == -1) { socket_boundary = max(0, min(GETDTABLESIZE() - FD_CHUNK, min(FOPEN_MAX, FD_PREFERRED_SOCKBOUNDARY))); -#ifdef DEBUG - msyslog(LOG_DEBUG, - "ntp_io: estimated max descriptors: %d, initial socket boundary: %d", - GETDTABLESIZE(), socket_boundary); -#endif + DPRINTF(1,("move_fd: estimated max descriptors: %d, " + "initial socket boundary: %d", + GETDTABLESIZE(), socket_boundary)); } /* @@ -128,7 +126,7 @@ move_fd( socket_boundary = max(0, socket_boundary - FD_CHUNK); #ifdef DEBUG msyslog(LOG_DEBUG, - "ntp_io: selecting new socket boundary: %d", + "move_fd: selecting new socket boundary: %d", socket_boundary); #endif } while (socket_boundary > 0); diff --git a/libntp/socktohost.c b/libntp/socktohost.c index 5f7925540..71cc8efe8 100644 --- a/libntp/socktohost.c +++ b/libntp/socktohost.c @@ -33,6 +33,8 @@ socktohost( struct addrinfo hints; struct addrinfo * alist; struct addrinfo * ai; + sockaddr_u addr; + size_t octets; int a_info; /* reverse the address to purported DNS name */ @@ -79,9 +81,20 @@ socktohost( NTP_INSIST(alist != NULL); - for (ai = alist; ai != NULL; ai = ai->ai_next) - if (SOCK_EQ(sock, (sockaddr_u *)ai->ai_addr)) + for (ai = alist; ai != NULL; ai = ai->ai_next) { + /* + * Make a convenience sockaddr_u copy from ai->ai_addr + * because casting from sockaddr * to sockaddr_u * is + * risking alignment problems on platforms where + * sockaddr_u has stricter alignment than sockaddr, + * such as sparc. + */ + ZERO_SOCK(&addr); + octets = min(sizeof(addr), ai->ai_addrlen); + memcpy(&addr, ai->ai_addr, octets); + if (SOCK_EQ(sock, &addr)) break; + } freeaddrinfo(alist); if (ai != NULL) diff --git a/libntp/ssl_init.c b/libntp/ssl_init.c index d652b41ae..0145f0dc6 100644 --- a/libntp/ssl_init.c +++ b/libntp/ssl_init.c @@ -16,19 +16,35 @@ #include "openssl/err.h" #include "openssl/evp.h" +void atexit_ssl_cleanup(void); int ssl_init_done; void ssl_init(void) { + init_lib(); + if (ssl_init_done) return; ERR_load_crypto_strings(); OpenSSL_add_all_algorithms(); + atexit(&atexit_ssl_cleanup); + + ssl_init_done = TRUE; +} + + +void +atexit_ssl_cleanup(void) +{ + if (!ssl_init_done) + return; - ssl_init_done = 1; + ssl_init_done = FALSE; + EVP_cleanup(); + ERR_free_strings(); } diff --git a/libntp/syssignal.c b/libntp/syssignal.c index cbdb02f2c..ad5574c9c 100644 --- a/libntp/syssignal.c +++ b/libntp/syssignal.c @@ -5,6 +5,9 @@ #include #include #include +#ifdef HAVE_LINUX_SIGNAL_H +#include /* provides SA_RESTORER on Linux */ +#endif #include "ntp_syslog.h" #include "ntp_stdlib.h" @@ -12,19 +15,31 @@ #ifdef HAVE_SIGACTION -#ifdef SA_RESTART -# define Z_SA_RESTART SA_RESTART -#else -# define Z_SA_RESTART 0 -#endif - +# ifdef SA_RESTART +# define Z_SA_RESTART SA_RESTART +# else +# define Z_SA_RESTART 0 +# endif # ifdef SA_SIGINFO -# define Z_SA_SIGINFO SA_SIGINFO +# define Z_SA_SIGINFO SA_SIGINFO +# else +# define Z_SA_SIGINFO 0 +# endif +# ifdef SA_NOCLDSTOP +# define Z_SA_NOCLDSTOP SA_NOCLDSTOP +# else +# define Z_SA_NOCLDSTOP 0 +# endif +# ifdef SA_RESTORER +# define Z_SA_RESTORER SA_RESTORER # else -# define Z_SA_SIGINFO 0 +# define Z_SA_RESTORER 0 # endif -# define IGNORED_SA_FLAGS (Z_SA_RESTART | Z_SA_SIGINFO) +# define IGNORED_SA_FLAGS (Z_SA_NOCLDSTOP | \ + Z_SA_RESTART | \ + Z_SA_RESTORER | \ + Z_SA_SIGINFO) void diff --git a/ntpd/work_fork.c b/libntp/work_fork.c similarity index 51% rename from ntpd/work_fork.c rename to libntp/work_fork.c index 2ec9d0d28..b7dc0ec99 100644 --- a/ntpd/work_fork.c +++ b/libntp/work_fork.c @@ -19,22 +19,18 @@ #include "ntp_unixtime.h" #include "ntp_worker.h" -/* - * pipe descriptors for both directions - * 0 indicates invalid/unopened, not descriptor 0. - */ -static int parent_req_write_pipe; - int parent_resp_read_pipe; -static int child_req_read_pipe; -static int child_resp_write_pipe; -static int blocking_worker_pid; -static volatile int worker_sighup_received; - -static void fork_blocking_child(void); -static RETSIGTYPE worker_sighup(int); -static void send_worker_home_atexit(void); - - +/* === variables === */ + int worker_process; + addremove_io_fd_func addremove_io_fd; +static volatile int worker_sighup_received; + +/* === function prototypes === */ +static void fork_blocking_child(blocking_child *); +static RETSIGTYPE worker_sighup(int); +static void send_worker_home_atexit(void); +static void cleanup_after_child(blocking_child *); + +/* === functions === */ /* * exit_worker() * @@ -71,7 +67,8 @@ worker_sighup( int worker_sleep( - time_t seconds + blocking_child * c, + time_t seconds ) { u_int sleep_remain; @@ -95,31 +92,86 @@ worker_sleep( void interrupt_worker_sleep(void) { - if (blocking_worker_pid != 0 && - -1 == kill(blocking_worker_pid, SIGHUP)) - msyslog(LOG_ERR, - "Unable to signal HUP to wake child pid %d: %m", - blocking_worker_pid); + u_int idx; + blocking_child * c; + int rc; + + for (idx = 0; idx < blocking_children_alloc; idx++) { + c = blocking_children[idx]; + if (NULL == c) + continue; + rc = kill(c->pid, SIGHUP); + if (rc < 0) + msyslog(LOG_ERR, + "Unable to signal HUP to wake child pid %d: %m", + c->pid); + } +} + + +/* + * req_child_exit() runs in the parent. + */ +int +req_child_exit( + blocking_child * c + ) +{ + if (-1 != c->req_write_pipe) { + close(c->req_write_pipe); + c->req_write_pipe = -1; + return 0; + } + return -1; +} + + +/* + * cleanup_after_child() runs in parent. + */ +static void +cleanup_after_child( + blocking_child * c + ) +{ + if (-1 != c->req_write_pipe) { + close(c->req_write_pipe); + c->req_write_pipe = -1; + } + if (-1 != c->resp_read_pipe) { + (*addremove_io_fd)(c->resp_read_pipe, c->ispipe, TRUE); + close(c->resp_read_pipe); + c->resp_read_pipe = -1; + } + c->pid = 0; + c->resp_read_ctx = NULL; + DEBUG_INSIST(-1 == c->req_read_pipe); + DEBUG_INSIST(-1 == c->resp_write_pipe); + c->reusable = TRUE; } static void send_worker_home_atexit(void) { - if (!parent_req_write_pipe) + u_int idx; + blocking_child * c; + + if (worker_process) return; - close(parent_req_write_pipe); - parent_req_write_pipe = 0; - close(parent_resp_read_pipe); - parent_resp_read_pipe = 0; - interrupt_worker_sleep(); - blocking_worker_pid = 0; + for (idx = 0; idx < blocking_children_alloc; idx++) { + c = blocking_children[idx]; + if (NULL == c) + continue; + req_child_exit(c); + } } int send_blocking_req_internal( + blocking_child * c, blocking_pipe_header * hdr, void * data ) @@ -127,31 +179,33 @@ send_blocking_req_internal( int octets; int rc; - NTP_REQUIRE(hdr != NULL); - NTP_REQUIRE(data != NULL); - NTP_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig); + DEBUG_REQUIRE(hdr != NULL); + DEBUG_REQUIRE(data != NULL); + DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig); - if (!parent_req_write_pipe) { - fork_blocking_child(); - NTP_INSIST(parent_req_write_pipe); + if (-1 == c->req_write_pipe) { + fork_blocking_child(c); + DEBUG_INSIST(-1 != c->req_write_pipe); } octets = sizeof(*hdr); - rc = write(parent_req_write_pipe, hdr, octets); + rc = write(c->req_write_pipe, hdr, octets); if (rc == octets) { octets = hdr->octets - sizeof(*hdr); - rc = write(parent_req_write_pipe, data, - octets); + rc = write(c->req_write_pipe, data, octets); if (rc == octets) return 0; } if (rc < 0) - msyslog(LOG_ERR, "send_blocking_req_internal: pipe write: %m"); + msyslog(LOG_ERR, + "send_blocking_req_internal: pipe write: %m"); else - msyslog(LOG_ERR, "send_blocking_req_internal: short write %d of %d\n", rc, octets); + msyslog(LOG_ERR, + "send_blocking_req_internal: short write %d of %d\n", + rc, octets); exit(1); /* otherwise would be return -1 */ } @@ -159,46 +213,47 @@ send_blocking_req_internal( blocking_pipe_header * receive_blocking_req_internal( - void + blocking_child * c ) { - blocking_pipe_header hdr; - blocking_pipe_header *req; - int rc; + blocking_pipe_header hdr; + blocking_pipe_header * req; + int rc; + long octets; - NTP_REQUIRE(child_req_read_pipe); + DEBUG_REQUIRE(-1 != c->req_read_pipe); req = NULL; do { - rc = read(child_req_read_pipe, &hdr, sizeof(hdr)); + rc = read(c->req_read_pipe, &hdr, sizeof(hdr)); } while (rc < 0 && EINTR == errno); - if (rc < 0) + if (rc < 0) { msyslog(LOG_ERR, "receive_blocking_req_internal: pipe read %m\n"); - else if (0 == rc) - DPRINTF(1, ("parent closed request pipe\n")); - else if (rc != sizeof(hdr)) + } else if (0 == rc) { + DPRINTF(4, ("parent closed request pipe, child %d terminating\n", + c->pid)); + } else if (rc != sizeof(hdr)) { msyslog(LOG_ERR, "receive_blocking_req_internal: short header read %d of %lu\n", rc, (u_long)sizeof(hdr)); - else { - NTP_INSIST(sizeof(hdr) < hdr.octets && hdr.octets < 4 * 1024); + } else { + INSIST(sizeof(hdr) < hdr.octets && hdr.octets < 4 * 1024); req = emalloc(hdr.octets); memcpy(req, &hdr, sizeof(*req)); - - rc = read(child_req_read_pipe, - (char *)req + sizeof(*req), - hdr.octets - sizeof(hdr)); + octets = hdr.octets - sizeof(hdr); + rc = read(c->req_read_pipe, (char *)req + sizeof(*req), + octets); if (rc < 0) msyslog(LOG_ERR, "receive_blocking_req_internal: pipe data read %m\n"); - else if (rc != hdr.octets - sizeof(hdr)) + else if (rc != octets) msyslog(LOG_ERR, - "receive_blocking_req_internal: short read %d of %lu\n", - rc, (u_long)(hdr.octets - sizeof(hdr))); + "receive_blocking_req_internal: short read %d of %ld\n", + rc, octets); else if (BLOCKING_REQ_MAGIC != req->magic_sig) msyslog(LOG_ERR, "receive_blocking_req_internal: packet header mismatch (0x%x)", @@ -207,7 +262,7 @@ receive_blocking_req_internal( return req; } - if (req) + if (req != NULL) free(req); return NULL; @@ -216,16 +271,17 @@ receive_blocking_req_internal( int send_blocking_resp_internal( - blocking_pipe_header *resp + blocking_child * c, + blocking_pipe_header * resp ) { - int octets; - int rc; + long octets; + int rc; - NTP_REQUIRE(child_resp_write_pipe); + DEBUG_REQUIRE(-1 != c->resp_write_pipe); octets = resp->octets; - rc = write(child_resp_write_pipe, resp, octets); + rc = write(c->resp_write_pipe, resp, octets); free(resp); if (octets == rc) @@ -234,7 +290,8 @@ send_blocking_resp_internal( if (rc < 0) DPRINTF(1, ("send_blocking_resp_internal: pipe write %m\n")); else - DPRINTF(1, ("send_blocking_resp_internal: short write %d of %d\n", rc, octets)); + DPRINTF(1, ("send_blocking_resp_internal: short write %d of %ld\n", + rc, octets)); return -1; } @@ -242,46 +299,51 @@ send_blocking_resp_internal( blocking_pipe_header * receive_blocking_resp_internal( - void + blocking_child * c ) { - blocking_pipe_header hdr; - blocking_pipe_header *resp; - int rc; + blocking_pipe_header hdr; + blocking_pipe_header * resp; + int rc; + long octets; - NTP_REQUIRE(parent_resp_read_pipe); + DEBUG_REQUIRE(c->resp_read_pipe != -1); resp = NULL; + rc = read(c->resp_read_pipe, &hdr, sizeof(hdr)); - rc = read(parent_resp_read_pipe, &hdr, sizeof(hdr)); - - if (rc < 0) + if (rc < 0) { DPRINTF(1, ("receive_blocking_resp_internal: pipe read %m\n")); - else if (rc != sizeof(hdr)) + } else if (0 == rc) { + /* this is the normal child exited indication */ + } else if (rc != sizeof(hdr)) { DPRINTF(1, ("receive_blocking_resp_internal: short header read %d of %lu\n", rc, (u_long)sizeof(hdr))); - else if (BLOCKING_RESP_MAGIC != hdr.magic_sig) + } else if (BLOCKING_RESP_MAGIC != hdr.magic_sig) { DPRINTF(1, ("receive_blocking_resp_internal: header mismatch (0x%x)\n", hdr.magic_sig)); - else { - NTP_INSIST(sizeof(hdr) < hdr.octets && hdr.octets < 16 * 1024); + } else { + INSIST(sizeof(hdr) < hdr.octets && + hdr.octets < 16 * 1024); resp = emalloc(hdr.octets); memcpy(resp, &hdr, sizeof(*resp)); - - rc = read(parent_resp_read_pipe, + octets = hdr.octets - sizeof(hdr); + rc = read(c->resp_read_pipe, (char *)resp + sizeof(*resp), - hdr.octets - sizeof(hdr)); + octets); if (rc < 0) DPRINTF(1, ("receive_blocking_resp_internal: pipe data read %m\n")); - else if (rc < hdr.octets - sizeof(hdr)) - DPRINTF(1, ("receive_blocking_resp_internal: short read %d of %lu\n", - rc, (u_long)(hdr.octets - sizeof(hdr)))); + else if (rc < octets) + DPRINTF(1, ("receive_blocking_resp_internal: short read %d of %ld\n", + rc, octets)); else return resp; } - if (resp) + cleanup_after_child(c); + + if (resp != NULL) free(resp); return NULL; @@ -292,25 +354,36 @@ receive_blocking_resp_internal( void fork_deferred_worker(void) { - NTP_REQUIRE(droproot); - NTP_REQUIRE(root_dropped); + u_int idx; + blocking_child * c; + + REQUIRE(droproot && root_dropped); - if (parent_req_write_pipe && !blocking_worker_pid) - fork_blocking_child(); + for (idx = 0; idx < blocking_children_alloc; idx++) { + c = blocking_children[idx]; + if (NULL == c) + continue; + if (-1 != c->req_write_pipe && 0 == c->pid) + fork_blocking_child(c); + } } #endif static void fork_blocking_child( - void + blocking_child * c ) { - static int atexit_installed; - static int blocking_pipes[4]; - int childpid; - int keep_fd; - int fd; + static int atexit_installed; + static int blocking_pipes[4] = { -1, -1, -1, -1 }; + int rc; + int was_pipe; + int is_pipe; + int saved_errno; + int childpid; + int keep_fd; + int fd; /* * parent and child communicate via a pair of pipes. @@ -320,9 +393,22 @@ fork_blocking_child( * 2 parent read response * 3 child write response */ - if (!parent_req_write_pipe) { - if (pipe(&blocking_pipes[0]) < 0 || - pipe(&blocking_pipes[2]) < 0) { + if (-1 == c->req_write_pipe) { + rc = pipe_socketpair(&blocking_pipes[0], &was_pipe); + if (0 != rc) { + saved_errno = errno; + } else { + rc = pipe_socketpair(&blocking_pipes[2], &is_pipe); + if (0 != rc) { + saved_errno = errno; + close(blocking_pipes[0]); + close(blocking_pipes[1]); + } else { + INSIST(was_pipe == is_pipe); + } + } + if (0 != rc) { + errno = saved_errno; msyslog(LOG_ERR, "unable to create worker pipes: %m"); exit(1); } @@ -331,11 +417,8 @@ fork_blocking_child( * Move the descriptors the parent will keep open out of the * low descriptors preferred by C runtime buffered FILE *. */ - parent_req_write_pipe = move_fd(blocking_pipes[1]); - parent_resp_read_pipe = move_fd(blocking_pipes[2]); - /* zero is reserved to mean invalid/not open */ - NTP_INSIST(parent_req_write_pipe != 0); - NTP_INSIST(parent_resp_read_pipe != 0); + c->req_write_pipe = move_fd(blocking_pipes[1]); + c->resp_read_pipe = move_fd(blocking_pipes[2]); /* * wake any worker child on orderly shutdown of the * daemon so that it can notice the broken pipes and @@ -343,7 +426,7 @@ fork_blocking_child( */ if (!atexit_installed) { atexit(&send_worker_home_atexit); - atexit_installed = 1; + atexit_installed = TRUE; } } @@ -367,40 +450,49 @@ fork_blocking_child( if (childpid) { /* this is the parent */ - NLOG(NLOG_SYSEVENT) - msyslog(LOG_INFO, - "forked worker child (pid %d)", - childpid); - blocking_worker_pid = childpid; + DPRINTF(1, ("forked worker child (pid %d)", childpid)); + c->pid = childpid; + c->ispipe = is_pipe; /* close the child's pipe descriptors. */ close(blocking_pipes[0]); close(blocking_pipes[3]); + memset(blocking_pipes, -1, sizeof(blocking_pipes)); + /* wire into I/O loop */ - update_resp_pipe_fd(parent_resp_read_pipe, 0); + (*addremove_io_fd)(c->resp_read_pipe, is_pipe, FALSE); return; /* parent returns */ } + /* + * The parent gets the child pid as the return value of fork(). + * The child must work for it. + */ + c->pid = getpid(); + worker_process = TRUE; + /* * In the child, close all files except stdin, stdout, stderr, * and the two child ends of the pipes. */ - child_req_read_pipe = blocking_pipes[0]; - child_resp_write_pipe = blocking_pipes[3]; + DEBUG_INSIST(-1 == c->req_read_pipe); + DEBUG_INSIST(-1 == c->resp_write_pipe); + c->req_read_pipe = blocking_pipes[0]; + c->resp_write_pipe = blocking_pipes[3]; kill_asyncio(0); closelog(); if (syslog_file != NULL) { fclose(syslog_file); syslog_file = NULL; - syslogit = 1; + syslogit = TRUE; } - keep_fd = max(child_req_read_pipe, child_resp_write_pipe); + keep_fd = max(c->req_read_pipe, c->resp_write_pipe); for (fd = 3; fd < keep_fd; fd++) - if (fd != child_req_read_pipe && - fd != child_resp_write_pipe) + if (fd != c->req_read_pipe && + fd != c->resp_write_pipe) close(fd); close_all_beyond(keep_fd); /* @@ -417,42 +509,13 @@ fork_blocking_child( signal_no_reset(SIGPOLL, SIG_DFL); #endif signal_no_reset(SIGHUP, worker_sighup); - init_logging("ntpd_intres", 0); - setup_logfile(0); + init_logging("ntp_intres", 0, NULL, FALSE); + setup_logfile(NULL, NULL); /* * And now back to the portable code */ - exit_worker(blocking_child_common()); -} - -/* - * worker_idle_timer_fired() - * - * The parent starts this timer when the last pending response has been - * received from the child, making it idle, and clears the timer when a - * request is dispatched to the child. Once the timer expires, the - * child is sent packing. - * - * This is called when worker_idle_timer is nonzero and less than or - * equal to current_time, and is responsible for resetting - * worker_idle_timer. - * - * Note there are implementations in both work_fork.c and work_thread.c - * that should remain in sync. - */ -void -worker_idle_timer_fired(void) -{ - NTP_REQUIRE(0 == intres_req_pending); - - worker_idle_timer = 0; - blocking_worker_pid = 0; - close(parent_req_write_pipe); - parent_req_write_pipe = 0; - update_resp_pipe_fd(parent_resp_read_pipe, 1); - close(parent_resp_read_pipe); - parent_resp_read_pipe = 0; + exit_worker(blocking_child_common(c)); } diff --git a/libntp/work_thread.c b/libntp/work_thread.c new file mode 100644 index 000000000..b4050b8d8 --- /dev/null +++ b/libntp/work_thread.c @@ -0,0 +1,660 @@ +/* + * work_thread.c - threads implementation for blocking worker child. + */ +#include +#include "ntp_workimpl.h" + +#ifdef WORK_THREAD + +#include +#include +#ifndef SYS_WINNT +#include +#endif + +#include "ntp_stdlib.h" +#include "ntp_malloc.h" +#include "ntp_syslog.h" +#include "ntpd.h" +#include "ntp_io.h" +#include "ntp_assert.h" +#include "ntp_unixtime.h" +#include "timespecops.h" +#include "ntp_worker.h" + +#define CHILD_EXIT_REQ ((blocking_pipe_header *)(intptr_t)-1) +#define CHILD_GONE_RESP CHILD_EXIT_REQ +#define WORKITEMS_ALLOC_INC 16 +#define RESPONSES_ALLOC_INC 4 + +#ifndef THREAD_MINSTACKSIZE +#define THREAD_MINSTACKSIZE (64U * 1024) +#endif + +#ifndef DEVOLATILE +#define DEVOLATILE(type, var) ((type)(uintptr_t)(volatile void *)(var)) +#endif + +#ifdef SYS_WINNT +# define thread_exit(c) _endthreadex(c) +# define tickle_sem SetEvent +#else +# define thread_exit(c) pthread_exit((void *)(c)) +# define tickle_sem sem_post +#endif + +#ifdef WORK_PIPE +addremove_io_fd_func addremove_io_fd; +#else +addremove_io_semaphore_func addremove_io_semaphore; +#endif + +static void start_blocking_thread(blocking_child *); +static void start_blocking_thread_internal(blocking_child *); +static void prepare_child_sems(blocking_child *); +static int wait_for_sem(sem_ref, struct timespec *); +static void ensure_workitems_empty_slot(blocking_child *); +static void ensure_workresp_empty_slot(blocking_child *); +static int queue_req_pointer(blocking_child *, blocking_pipe_header *); +static void cleanup_after_child(blocking_child *); +#ifdef SYS_WINNT +u_int WINAPI blocking_thread(void *); +#else +void * blocking_thread(void *); +#endif + + +void +exit_worker( + int exitcode + ) +{ + thread_exit(exitcode); /* see #define thread_exit */ +} + + +int +worker_sleep( + blocking_child * c, + time_t seconds + ) +{ + struct timespec until; + int rc; + +# ifdef HAVE_CLOCK_GETTIME + clock_gettime(CLOCK_REALTIME, &until); +# else + getclock(TIMEOFDAY, &until); +# endif + until.tv_sec += seconds; + do { + rc = wait_for_sem(c->wake_scheduled_sleep, &until); + } while (-1 == rc && EINTR == errno); + if (0 == rc) + return -1; + if (-1 == rc && ETIMEDOUT == errno) + return 0; + msyslog(LOG_ERR, "worker_sleep sem_timedwait %m"); + return -1; +} + + +void +interrupt_worker_sleep(void) +{ + u_int idx; + blocking_child * c; + + for (idx = 0; idx < blocking_children_alloc; idx++) { + c = blocking_children[idx]; + if (NULL == c || NULL == c->wake_scheduled_sleep) + continue; + tickle_sem(c->wake_scheduled_sleep); + } +} + + +static void +ensure_workitems_empty_slot( + blocking_child *c + ) +{ + const size_t each = sizeof(blocking_children[0]->workitems[0]); + size_t new_alloc; + size_t old_octets; + size_t new_octets; + void * nonvol_workitems; + + + if (c->workitems != NULL && + NULL == c->workitems[c->next_workitem]) + return; + + new_alloc = c->workitems_alloc + WORKITEMS_ALLOC_INC; + old_octets = c->workitems_alloc * each; + new_octets = new_alloc * each; + nonvol_workitems = DEVOLATILE(void *, c->workitems); + c->workitems = erealloc_zero(nonvol_workitems, new_octets, + old_octets); + if (0 == c->next_workitem) + c->next_workitem = c->workitems_alloc; + c->workitems_alloc = new_alloc; +} + + +static void +ensure_workresp_empty_slot( + blocking_child *c + ) +{ + const size_t each = sizeof(blocking_children[0]->responses[0]); + size_t new_alloc; + size_t old_octets; + size_t new_octets; + void * nonvol_responses; + + if (c->responses != NULL && + NULL == c->responses[c->next_response]) + return; + + new_alloc = c->responses_alloc + RESPONSES_ALLOC_INC; + old_octets = c->responses_alloc * each; + new_octets = new_alloc * each; + nonvol_responses = DEVOLATILE(void *, c->responses); + c->responses = erealloc_zero(nonvol_responses, new_octets, + old_octets); + if (0 == c->next_response) + c->next_response = c->responses_alloc; + c->responses_alloc = new_alloc; +} + + +/* + * queue_req_pointer() - append a work item or idle exit request to + * blocking_workitems[]. + */ +static int +queue_req_pointer( + blocking_child * c, + blocking_pipe_header * hdr + ) +{ + c->workitems[c->next_workitem] = hdr; + c->next_workitem = (1 + c->next_workitem) % c->workitems_alloc; + + /* + * We only want to signal the wakeup event if the child is + * blocking on it, which is indicated by setting the blocking + * event. Wait with zero timeout to test. + */ + /* !!!! if (WAIT_OBJECT_0 == WaitForSingleObject(c->child_is_blocking, 0)) */ + tickle_sem(c->blocking_req_ready); + + return 0; +} + + +int +send_blocking_req_internal( + blocking_child * c, + blocking_pipe_header * hdr, + void * data + ) +{ + blocking_pipe_header * threadcopy; + + DEBUG_REQUIRE(hdr != NULL); + DEBUG_REQUIRE(hdr->octets > sizeof(*hdr)); + DEBUG_REQUIRE(data != NULL); + DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig); + + ensure_workitems_empty_slot(c); + if (NULL == c->thread_ref) { + ensure_workresp_empty_slot(c); + start_blocking_thread(c); + } + + threadcopy = emalloc(hdr->octets); + memcpy(threadcopy, hdr, sizeof(*hdr)); + memcpy((char *)threadcopy + sizeof(*hdr), + data, hdr->octets - sizeof(*hdr)); + + return queue_req_pointer(c, threadcopy); +} + + +blocking_pipe_header * +receive_blocking_req_internal( + blocking_child * c + ) +{ + blocking_pipe_header * req; + int rc; + + /* + * Child blocks here when idle. SysV semaphores maintain a + * count and release from sem_wait() only when it reaches 0. + * Windows auto-reset events are simpler, and multiple SetEvent + * calls before any thread waits result in a single wakeup. + * On Windows, the child drains all workitems each wakeup, while + * with SysV semaphores wait_sem() is used before each item. + */ +#ifdef SYS_WINNT + while (NULL == c->workitems[c->next_workeritem]) { + /* !!!! SetEvent(c->child_is_blocking); */ + rc = wait_for_sem(c->blocking_req_ready, NULL); + INSIST(0 == rc); + /* !!!! ResetEvent(c->child_is_blocking); */ + } +#else + do { + rc = wait_for_sem(c->blocking_req_ready, NULL); + } while (-1 == rc && EINTR == errno); + INSIST(0 == rc); +#endif + + req = c->workitems[c->next_workeritem]; + INSIST(NULL != req); + c->workitems[c->next_workeritem] = NULL; + c->next_workeritem = (1 + c->next_workeritem) % + c->workitems_alloc; + + if (CHILD_EXIT_REQ == req) { /* idled out */ + send_blocking_resp_internal(c, CHILD_GONE_RESP); + req = NULL; + } + + return req; +} + + +int +send_blocking_resp_internal( + blocking_child * c, + blocking_pipe_header * resp + ) +{ + ensure_workresp_empty_slot(c); + + c->responses[c->next_response] = resp; + c->next_response = (1 + c->next_response) % c->responses_alloc; + +#ifdef WORK_PIPE + write(c->resp_write_pipe, "", 1); +#else + tickle_sem(c->blocking_response_ready); +#endif + + return 0; +} + + +#ifndef WORK_PIPE +void +handle_blocking_resp_sem( + void * context + ) +{ + HANDLE ready; + blocking_child * c; + u_int idx; + + ready = (HANDLE)context; + c = NULL; + for (idx = 0; idx < blocking_children_alloc; idx++) { + c = blocking_children[idx]; + if (c != NULL && c->thread_ref != NULL && + ready == c->blocking_response_ready) + break; + } + if (idx < blocking_children_alloc) + process_blocking_resp(c); +} +#endif /* !WORK_PIPE */ + + +blocking_pipe_header * +receive_blocking_resp_internal( + blocking_child * c + ) +{ + blocking_pipe_header * removed; +#ifdef WORK_PIPE + int rc; + char scratch[32]; + + do { + rc = read(c->resp_read_pipe, scratch, sizeof(scratch)); + } while (-1 == rc && EINTR == errno); +#endif + removed = c->responses[c->next_workresp]; + if (NULL != removed) { + c->responses[c->next_workresp] = NULL; + c->next_workresp = (1 + c->next_workresp) % + c->responses_alloc; + DEBUG_ENSURE(CHILD_GONE_RESP == removed || + BLOCKING_RESP_MAGIC == removed->magic_sig); + } + if (CHILD_GONE_RESP == removed) { + cleanup_after_child(c); + removed = NULL; + } + + return removed; +} + + +static void +start_blocking_thread( + blocking_child * c + ) +{ + + DEBUG_INSIST(!c->reusable); + + prepare_child_sems(c); + start_blocking_thread_internal(c); +} + + +static void +start_blocking_thread_internal( + blocking_child * c + ) +#ifdef SYS_WINNT +{ + thr_ref blocking_child_thread; + u_int blocking_thread_id; + BOOL resumed; + + (*addremove_io_semaphore)(c->blocking_response_ready, FALSE); + blocking_child_thread = + (HANDLE)_beginthreadex( + NULL, + 0, + &blocking_thread, + c, + CREATE_SUSPENDED, + &blocking_thread_id); + + if (NULL == blocking_child_thread) { + DPRINTF(1, ("fatal can not start blocking thread\n")); + exit(-1); + } + c->thread_id = blocking_thread_id; + c->thread_ref = blocking_child_thread; + /* remember the thread priority is only within the process class */ + if (!SetThreadPriority(blocking_child_thread, + THREAD_PRIORITY_BELOW_NORMAL)) + DPRINTF(1, ("Error lowering blocking thread priority\n")); + + resumed = ResumeThread(blocking_child_thread); + DEBUG_INSIST(resumed); +} +#else /* pthreads start_blocking_thread_internal() follows */ +{ +# ifdef NEED_PTHREAD_INIT + static int pthread_init_called; +# endif + pthread_attr_t thr_attr; + int rc; + int saved_errno; + int pipe_ends[2]; /* read then write */ + int is_pipe; + int flags; + size_t stacksize; + +# ifdef NEED_PTHREAD_INIT + /* + * from lib/isc/unix/app.c: + * BSDI 3.1 seg faults in pthread_sigmask() if we don't do this. + */ + if (!pthread_init_called) { + pthread_init(); + pthread_init_called = TRUE; + } +# endif + + rc = pipe_socketpair(&pipe_ends[0], &is_pipe); + if (0 != rc) { + msyslog(LOG_ERR, "start_blocking_thread: pipe_socketpair() %m"); + exit(1); + } + c->resp_read_pipe = move_fd(pipe_ends[0]); + c->resp_write_pipe = move_fd(pipe_ends[1]); + c->ispipe = is_pipe; + flags = fcntl(c->resp_read_pipe, F_GETFL, 0); + if (-1 == flags) { + msyslog(LOG_ERR, "start_blocking_thread: fcntl(F_GETFL) %m"); + exit(1); + } + rc = fcntl(c->resp_read_pipe, F_SETFL, O_NONBLOCK | flags); + if (-1 == rc) { + msyslog(LOG_ERR, + "start_blocking_thread: fcntl(F_SETFL, O_NONBLOCK) %m"); + exit(1); + } + (*addremove_io_fd)(c->resp_read_pipe, c->ispipe, FALSE); + pthread_attr_init(&thr_attr); + pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED); +#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \ + defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE) + rc = pthread_attr_getstacksize(&thr_attr, &stacksize); + if (-1 == rc) { + msyslog(LOG_ERR, + "start_blocking_thread: pthread_attr_getstacksize %m"); + } else if (stacksize < THREAD_MINSTACKSIZE) { + rc = pthread_attr_setstacksize(&thr_attr, + THREAD_MINSTACKSIZE); + if (-1 == rc) + msyslog(LOG_ERR, + "start_blocking_thread: pthread_attr_setstacksize(0x%lx -> 0x%lx) %m", + (u_long)stacksize, + (u_long)THREAD_MINSTACKSIZE); + } +#else + UNUSED_ARG(stacksize); +#endif +#if defined(PTHREAD_SCOPE_SYSTEM) && defined(NEED_PTHREAD_SCOPE_SYSTEM) + pthread_attr_setscope(&thr_attr, PTHREAD_SCOPE_SYSTEM); +#endif + c->thread_ref = emalloc_zero(sizeof(*c->thread_ref)); + rc = pthread_create(c->thread_ref, &thr_attr, + &blocking_thread, c); + saved_errno = errno; + pthread_attr_destroy(&thr_attr); + if (0 != rc) { + errno = saved_errno; + msyslog(LOG_ERR, "pthread_create() blocking child: %m"); + exit(1); + } +} +#endif + +/* + * prepare_child_sems() + * + * create sync events (semaphores) + * child_is_blocking initially unset + * blocking_req_ready initially unset + * + * Child waits for blocking_req_ready to be set after + * setting child_is_blocking. blocking_req_ready and + * blocking_response_ready are auto-reset, so wake one + * waiter and become unset (unsignalled) in one operation. + */ +static void +prepare_child_sems( + blocking_child *c + ) +#ifdef SYS_WINNT +{ + if (NULL == c->blocking_req_ready) { + /* manual reset using ResetEvent() */ + /* !!!! c->child_is_blocking = CreateEvent(NULL, TRUE, FALSE, NULL); */ + /* auto reset - one thread released from wait each set */ + c->blocking_req_ready = CreateEvent(NULL, FALSE, FALSE, NULL); + c->blocking_response_ready = CreateEvent(NULL, FALSE, FALSE, NULL); + c->wake_scheduled_sleep = CreateEvent(NULL, FALSE, FALSE, NULL); + } else { + /* !!!! ResetEvent(c->child_is_blocking); */ + /* ResetEvent(c->blocking_req_ready); */ + /* ResetEvent(c->blocking_response_ready); */ + /* ResetEvent(c->wake_scheduled_sleep); */ + } +} +#else /* pthreads prepare_child_sems() follows */ +{ + size_t octets; + + if (NULL == c->blocking_req_ready) { + octets = sizeof(*c->blocking_req_ready); + octets += sizeof(*c->wake_scheduled_sleep); + /* !!!! octets += sizeof(*c->child_is_blocking); */ + c->blocking_req_ready = emalloc_zero(octets);; + c->wake_scheduled_sleep = 1 + c->blocking_req_ready; + /* !!!! c->child_is_blocking = 1 + c->wake_scheduled_sleep; */ + } else { + sem_destroy(c->blocking_req_ready); + sem_destroy(c->wake_scheduled_sleep); + /* !!!! sem_destroy(c->child_is_blocking); */ + } + sem_init(c->blocking_req_ready, FALSE, 0); + sem_init(c->wake_scheduled_sleep, FALSE, 0); + /* !!!! sem_init(c->child_is_blocking, FALSE, 0); */ +} +#endif + + +static int +wait_for_sem( + sem_ref sem, + struct timespec * timeout /* wall-clock */ + ) +#ifdef SYS_WINNT +{ + struct timespec now; + struct timespec delta; + DWORD msec; + DWORD rc; + + if (NULL == timeout) { + msec = INFINITE; + } else { + getclock(TIMEOFDAY, &now); + timespec_sub(&delta, timeout, &now); + if (delta.tv_sec < 0) { + msec = 0; + } else if ((delta.tv_sec + 1) >= (MAXDWORD / 1000)) { + msec = INFINITE; + } else { + msec = 1000 * (DWORD)delta.tv_sec; + msec += delta.tv_nsec / (1000 * 1000); + } + } + rc = WaitForSingleObject(sem, msec); + if (WAIT_OBJECT_0 == rc) + return 0; + if (WAIT_TIMEOUT == rc) { + errno = ETIMEDOUT; + return -1; + } + msyslog(LOG_ERR, "WaitForSingleObject unexpected 0x%x", rc); + errno = EFAULT; + return -1; +} +#else /* pthreads wait_for_sem() follows */ +{ + int rc; + + if (NULL == timeout) + rc = sem_wait(sem); + else + rc = sem_timedwait(sem, timeout); + + return rc; +} +#endif + + +/* + * blocking_thread - thread functions have WINAPI calling convention + */ +#ifdef SYS_WINNT +u_int +WINAPI +#else +void * +#endif +blocking_thread( + void * ThreadArg + ) +{ + blocking_child *c; + + c = ThreadArg; + exit_worker(blocking_child_common(c)); + + /* NOTREACHED */ + return 0; +} + + +/* + * req_child_exit() runs in the parent. + */ +int +req_child_exit( + blocking_child *c + ) +{ + return queue_req_pointer(c, CHILD_EXIT_REQ); +} + + +/* + * cleanup_after_child() runs in parent. + */ +static void +cleanup_after_child( + blocking_child * c + ) +{ + u_int idx; + + DEBUG_INSIST(!c->reusable); +#ifdef SYS_WINNT + INSIST(CloseHandle(c->thread_ref)); +#else + free(c->thread_ref); +#endif + c->thread_ref = NULL; + c->thread_id = 0; +#ifdef WORK_PIPE + DEBUG_INSIST(-1 != c->resp_read_pipe); + DEBUG_INSIST(-1 != c->resp_write_pipe); + (*addremove_io_fd)(c->resp_read_pipe, c->ispipe, TRUE); + close(c->resp_write_pipe); + close(c->resp_read_pipe); + c->resp_write_pipe = -1; + c->resp_read_pipe = -1; +#else + DEBUG_INSIST(NULL != c->blocking_response_ready); + (*addremove_io_semaphore)(c->blocking_response_ready, TRUE); +#endif + for (idx = 0; idx < c->workitems_alloc; idx++) + c->workitems[idx] = NULL; + c->next_workitem = 0; + c->next_workeritem = 0; + for (idx = 0; idx < c->responses_alloc; idx++) + c->responses[idx] = NULL; + c->next_response = 0; + c->next_workresp = 0; + c->reusable = TRUE; +} + + +#else /* !WORK_THREAD follows */ +char work_thread_nonempty_compilation_unit; +#endif diff --git a/libparse/Makefile.am b/libparse/Makefile.am index a273f1fa6..d61dba813 100644 --- a/libparse/Makefile.am +++ b/libparse/Makefile.am @@ -58,7 +58,7 @@ libparse_kernel_a_LIBADD = \ INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += -I$(top_srcdir)/kernel diff --git a/libparse/parsesolaris.c b/libparse/parsesolaris.c index aa3572d60..ecd3fa2eb 100644 --- a/libparse/parsesolaris.c +++ b/libparse/parsesolaris.c @@ -292,7 +292,7 @@ setup_stream( mp = allocb(sizeof(struct stroptions), BPRI_MED); if (mp) { - struct stroptions *str = (struct stroptions *)mp->b_wptr; + struct stroptions *str = (void *)mp->b_wptr; str->so_flags = SO_READOPT|SO_HIWAT|SO_LOWAT|SO_ISNTTY; str->so_readopt = (mode == M_PARSE) ? RMSGD : RNORM; @@ -487,7 +487,7 @@ parsewput( break; case M_IOCTL: - iocp = (struct iocblk *)mp->b_rptr; + iocp = (void *)mp->b_rptr; switch (iocp->ioc_cmd) { default: @@ -511,7 +511,8 @@ parsewput( } mp->b_cont = datap; - *(struct ppsclockev *)datap->b_wptr = parse->parse_ppsclockev; + /* (void *) quiets cast alignment warning */ + *(struct ppsclockev *)(void *)datap->b_wptr = parse->parse_ppsclockev; datap->b_wptr += sizeof(struct ppsclockev) / sizeof(*datap->b_wptr); mp->b_datap->db_type = M_IOCACK; @@ -544,7 +545,7 @@ parsewput( case PARSEIOC_SETCS: if (iocp->ioc_count == sizeof(parsectl_t)) { - parsectl_t *dct = (parsectl_t *)mp->b_cont->b_rptr; + parsectl_t *dct = (void *)mp->b_cont->b_rptr; switch (iocp->ioc_cmd) { @@ -987,7 +988,7 @@ zs_xsisr( struct zscom *zs ) { - register struct asyncline *za = (struct asyncline *)zs->zs_priv; + register struct asyncline *za = (void *)zs->zs_priv; register queue_t *q; register unsigned char zsstatus; register int loopcheck; diff --git a/ntpd/Makefile.am b/ntpd/Makefile.am index 1f4ec3860..a7e6e7430 100644 --- a/ntpd/Makefile.am +++ b/ntpd/Makefile.am @@ -11,7 +11,7 @@ noinst_LIBRARIES= libntpd.a INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += $(LIBOPTS_CFLAGS) @@ -19,8 +19,8 @@ AM_CFLAGS = @CFLAGS_NTP@ AM_CPPFLAGS = @CPPFLAGS_NTP@ # LDADD might need RESLIB and ADJLIB. -LDADD= version.o libntpd.a @LIBPARSE@ -AM_YFLAGS= -d -t -r all +LDADD = version.o libntpd.a @LIBPARSE@ +AM_YFLAGS = -d -t -r all if SAVECONFIG_ENABLED if NTP_CROSSCOMPILE @@ -89,11 +89,14 @@ man_MANS= $(srcdir)/ntpd.1 # simulator currently uses ntpd-opts.[ch]. This also means there is no # longer a reason to have ntpdbase-opts.def split off of ntpd-opts.def. -ntpd_LDADD = $(LDADD) $(LIBOPTS_LDADD) ../libntp/libntp.a $(LIBM) @LCRYPTO@ @LSCF@ -ntpdsim_LDADD = $(LDADD) $(LIBOPTS_LDADD) $(LIBM) ../libntp/libntpsim.a @LCRYPTO@ @LSCF@ -ntpdsim_CFLAGS = $(CFLAGS) -DSIM -check_y2k_LDADD = $(LDADD) ../libntp/libntp.a -keyword_gen_LDADD = ../libntp/libntp.a # we don't want $(LDADD) here +LDADD_NTPD_COMMON = @LDADD_LIBNTP@ $(LIBOPTS_LDADD) @PTHREAD_LIBS@ +LDADD_NTPD_COMMON += $(LIBM) @LCRYPTO@ @LSCF@ +ntpd_LDADD = $(LDADD) ../libntp/libntp.a $(LDADD_NTPD_COMMON) +ntpdsim_LDADD = $(LDADD) ../libntp/libntpsim.a $(LDADD_NTPD_COMMON) +ntpdsim_CPPFLAGS = $(AM_CPPFLAGS) -DSIM +check_y2k_LDADD = $(LDADD) ../libntp/libntp.a @LDADD_LIBNTP@ @PTHREAD_LIBS@ +## we don't want $(LDADD) in keyword_gen_LDADD +keyword_gen_LDADD = ../libntp/libntp.a @LDADD_LIBNTP@ @PTHREAD_LIBS@ DISTCLEANFILES = \ keyword-gen \ @@ -164,7 +167,6 @@ libntpd_a_SOURCES = \ ntp_control.c \ ntp_crypto.c \ ntp_filegen.c \ - ntp_intres.c \ ntp_loopfilter.c \ ntp_monitor.c \ ntp_peer.c \ @@ -175,7 +177,6 @@ libntpd_a_SOURCES = \ ntp_signd.c \ ntp_timer.c \ ntp_util.c \ - ntp_worker.c \ ppsapi_timepps.h \ refclock_acts.c \ refclock_arbiter.c \ @@ -217,8 +218,6 @@ libntpd_a_SOURCES = \ refclock_wwv.c \ refclock_wwvb.c \ refclock_zyfer.c \ - work_fork.c \ - work_thread.c \ $(NULL) k-g-u-submake: keyword-gen diff --git a/ntpd/cmd_args.c b/ntpd/cmd_args.c index b4e8e9b33..0b54d5b2b 100644 --- a/ntpd/cmd_args.c +++ b/ntpd/cmd_args.c @@ -133,8 +133,11 @@ getCmdOpts( droproot = 1; user = estrdup(OPT_ARG( USER )); group = strrchr(user, ':'); - if (group != NULL) + if (group != NULL) { *group++ = '\0'; /* get rid of the ':' */ + group = estrdup(group); + user = erealloc(user, group - user); + } } #endif diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 1ac8b4374..695a0db33 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -30,6 +30,9 @@ # include #endif +#include +#include + #include "ntp.h" #include "ntpd.h" #include "ntp_io.h" @@ -39,23 +42,16 @@ #include "ntp_stdlib.h" #include "lib_strbuf.h" #include "ntp_assert.h" -#include "ntpd-opts.h" #include "ntp_random.h" -#include "ntp_workimpl.h" -#include -#include - - /* * [Bug 467]: Some linux headers collide with CONFIG_PHONE and CONFIG_KEYS * so #include these later. */ - #include "ntp_config.h" #include "ntp_cmdargs.h" - #include "ntp_scanner.h" #include "ntp_parser.h" +#include "ntpd-opts.h" /* list of servers from command line for config_peers() */ @@ -1628,7 +1624,7 @@ get_next_address( char addr_string[ADDR_LENGTH]; sockaddr_u *final_addr; struct addrinfo *ptr; - int gai_error; + int gai_err; final_addr = emalloc(sizeof(*final_addr)); @@ -1637,12 +1633,12 @@ get_next_address( addr_prefix, curr_addr_num++); printf("Selecting ip address %s for hostname %s\n", addr_string, addr->address); - gai_error = getaddrinfo(addr_string, "ntp", NULL, &ptr); + gai_err = getaddrinfo(addr_string, "ntp", NULL, &ptr); } else { - gai_error = getaddrinfo(addr->address, "ntp", NULL, &ptr); + gai_err = getaddrinfo(addr->address, "ntp", NULL, &ptr); } - if (gai_error) { + if (gai_err) { fprintf(stderr, "ERROR!! Could not get a new address\n"); exit(1); } @@ -4197,7 +4193,7 @@ getconfig( char ** argv ) { - char line[MAXLINE]; + char line[256]; #ifdef DEBUG atexit(free_all_config_trees); @@ -4206,14 +4202,16 @@ getconfig( config_file = CONFIG_FILE; #else temp = CONFIG_FILE; - if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)config_file_storage, (DWORD)sizeof(config_file_storage))) { + if (!ExpandEnvironmentStringsA(temp, config_file_storage, + sizeof(config_file_storage))) { msyslog(LOG_ERR, "ExpandEnvironmentStrings CONFIG_FILE failed: %m\n"); exit(1); } config_file = config_file_storage; temp = ALT_CONFIG_FILE; - if (!ExpandEnvironmentStrings((LPCTSTR)temp, (LPTSTR)alt_config_file_storage, (DWORD)sizeof(alt_config_file_storage))) { + if (!ExpandEnvironmentStringsA(temp, alt_config_file_storage, + sizeof(alt_config_file_storage))) { msyslog(LOG_ERR, "ExpandEnvironmentStrings ALT_CONFIG_FILE failed: %m\n"); exit(1); } @@ -4224,7 +4222,7 @@ getconfig( * install a non default variable with this daemon version */ snprintf(line, sizeof(line), "daemon_version=\"%s\"", Version); - set_sys_var(line, strlen(line)+1, RO); + set_sys_var(line, strlen(line) + 1, RO); /* * Set up for the first time step to install a variable showing @@ -4327,10 +4325,9 @@ save_and_apply_config_tree(void) dumpfile = fopen(OPT_ARG( SAVECONFIGQUIT ), "w"); if (NULL == dumpfile) { err = errno; - fprintf(stderr, - "can not create save file %s, error %d %s\n", - OPT_ARG( SAVECONFIGQUIT ), err, - strerror(err)); + mfprintf(stderr, + "can not create save file %s, error %d %m\n", + OPT_ARG(SAVECONFIGQUIT), err); exit(err); } diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index fb7881806..fd025bb4f 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -1008,8 +1008,8 @@ process_control( req_count = (int)ntohs(pkt->count); datanotbinflag = 0; datalinelen = 0; - datapt = rpkt.data; - dataend = &(rpkt.data[CTL_MAX_DATA_LEN]); + datapt = rpkt.u.data; + dataend = &rpkt.u.data[CTL_MAX_DATA_LEN]; if ((rbufp->recv_length & 0x3) != 0) DPRINTF(3, ("Control packet length %d unrounded\n", @@ -1057,7 +1057,7 @@ process_control( /* * Set up translate pointers */ - reqpt = (char *)pkt->data; + reqpt = (char *)pkt->u.data; reqend = reqpt + req_count; /* @@ -1168,7 +1168,7 @@ ctl_flushpkt( int totlen; keyid_t keyid; - dlen = datapt - rpkt.data; + dlen = datapt - rpkt.u.data; if (!more && datanotbinflag && dlen + 2 < CTL_MAX_DATA_LEN) { /* * Big hack, output a trailing \r\n @@ -1243,7 +1243,7 @@ ctl_flushpkt( * Set us up for another go around. */ res_offset += dlen; - datapt = rpkt.data; + datapt = rpkt.u.data; } @@ -1264,7 +1264,7 @@ ctl_putdata( if (!bin) { datanotbinflag = 1; overhead = 3; - if (datapt != rpkt.data) { + if (datapt != rpkt.u.data) { *datapt++ = ','; datalinelen++; if ((dlen + datalinelen + 1) >= MAXDATALINELEN) { @@ -4302,8 +4302,8 @@ report_event( res_offset = 0; res_async = 1; res_authenticate = 0; - datapt = rpkt.data; - dataend = &(rpkt.data[CTL_MAX_DATA_LEN]); + datapt = rpkt.u.data; + dataend = &rpkt.u.data[CTL_MAX_DATA_LEN]; if (!(err & PEER_EVENT)) { rpkt.associd = 0; rpkt.status = htons(ctlsysstatus()); diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index a4f9b4e7f..e71f27e09 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -29,8 +29,8 @@ #include "ntp_lists.h" #include "ntp_refclock.h" #include "ntp_stdlib.h" +#include "ntp_worker.h" #include "ntp_request.h" -#include "ntp.h" #include "ntp_unixtime.h" #include "ntp_assert.h" #include "ntpd-opts.h" @@ -162,12 +162,6 @@ static struct refclockio *refio; fd_set activefds; int maxactivefd; -#ifndef HAVE_IO_COMPLETION_PORT -static void maintain_activefds(int fd, int closing); -#else -#define maintain_activefds(fd, closing) do {} while (0) -#endif - /* * bit alternating value to detect verified interfaces during an update cycle */ @@ -296,14 +290,15 @@ static int cmp_addr_distance(const sockaddr_u *, * Routines to read the ntp packets */ #if !defined(HAVE_IO_COMPLETION_PORT) -static inline int read_network_packet (SOCKET, struct interface *, l_fp); -static inline int read_refclock_packet (SOCKET, struct refclockio *, l_fp); +static inline int read_network_packet (SOCKET, struct interface *, l_fp); +static inline int read_refclock_packet (SOCKET, struct refclockio *, l_fp); +void ntpd_addremove_io_fd (int, int, int); #endif #ifndef HAVE_IO_COMPLETION_PORT -static void +void maintain_activefds( int fd, int closing @@ -336,189 +331,6 @@ maintain_activefds( #endif /* !HAVE_IO_COMPLETION_PORT */ -#ifdef WORK_FORK -void -update_resp_pipe_fd( - int resp_pipe_fd, - int closing - ) -{ - maintain_activefds(resp_pipe_fd, closing); -} -#endif - - -/* MOVED to libntp/socket.c for inclusion by libntp */ -#if 0 -/* - * on Unix systems the stdio library typically - * makes use of file descriptors in the lower - * integer range. stdio usually will make use - * of the file descriptors in the range of - * [0..FOPEN_MAX) - * in order to keep this range clean, for socket - * file descriptors we attempt to move them above - * FOPEN_MAX. This is not as easy as it sounds as - * FOPEN_MAX changes from implementation to implementation - * and may exceed to current file decriptor limits. - * We are using following strategy: - * - keep a current socket fd boundary initialized with - * max(0, min(GETDTABLESIZE() - FD_CHUNK, FOPEN_MAX)) - * - attempt to move the descriptor to the boundary or - * above. - * - if that fails and boundary > 0 set boundary - * to min(0, socket_fd_boundary - FD_CHUNK) - * -> retry - * if failure and boundary == 0 return old fd - * - on success close old fd return new fd - * - * effects: - * - fds will be moved above the socket fd boundary - * if at all possible. - * - the socket boundary will be reduced until - * allocation is possible or 0 is reached - at this - * point the algrithm will be disabled - */ -SOCKET -move_fd( - SOCKET fd - ) -{ -#if !defined(SYS_WINNT) && defined(F_DUPFD) -#ifndef FD_CHUNK -#define FD_CHUNK 10 -#endif -#ifndef FOPEN_MAX -#define FOPEN_MAX 20 -#endif -/* - * number of fds we would like to have for - * stdio FILE* available. - * we can pick a "low" number as our use of - * FILE* is limited to log files and temporarily - * to data and config files. Except for log files - * we don't keep the other FILE* open beyond the - * scope of the function that opened it. - */ -#ifndef FD_PREFERRED_SOCKBOUNDARY -#define FD_PREFERRED_SOCKBOUNDARY 48 -#endif - -#if defined(HAVE_SYSCONF) && defined(_SC_OPEN_MAX) -#define GETDTABLESIZE() ((int)sysconf(_SC_OPEN_MAX)) -#elif !defined(HAVE_GETDTABLESIZE) -/* - * if we have no idea about the max fd value set up things - * so we will start at FOPEN_MAX - */ -#define GETDTABLESIZE() (FOPEN_MAX + FD_CHUNK) -#endif - - static SOCKET socket_boundary = -1; - SOCKET newfd; - - NTP_REQUIRE((int)fd >= 0); - - /* - * check whether boundary has be set up - * already - */ - if (socket_boundary == -1) { - socket_boundary = max(0, min(GETDTABLESIZE() - FD_CHUNK, - min(FOPEN_MAX, FD_PREFERRED_SOCKBOUNDARY))); -#ifdef DEBUG - msyslog(LOG_DEBUG, - "ntp_io: estimated max descriptors: %d, initial socket boundary: %d", - GETDTABLESIZE(), socket_boundary); -#endif - } - - /* - * Leave a space for stdio to work in. potentially moving the - * socket_boundary lower until allocation succeeds. - */ - do { - if (fd >= 0 && fd < socket_boundary) { - /* inside reserved range: attempt to move fd */ - newfd = fcntl(fd, F_DUPFD, socket_boundary); - - if (newfd != -1) { - /* success: drop the old one - return the new one */ - close(fd); - return newfd; - } - } else { - /* outside reserved range: no work - return the original one */ - return fd; - } - socket_boundary = max(0, socket_boundary - FD_CHUNK); -#ifdef DEBUG - msyslog(LOG_DEBUG, - "ntp_io: selecting new socket boundary: %d", - socket_boundary); -#endif - } while (socket_boundary > 0); -#else - NTP_REQUIRE((int)fd >= 0); -#endif /* !defined(SYS_WINNT) && defined(F_DUPFD) */ - return fd; -} -#endif /* 0 */ - - -#ifndef HAVE_IO_COMPLETION_PORT -/* - * close_all_except() - * - * Close all file descriptors except the given keep_fd. - */ -void -close_all_except( - int keep_fd - ) -{ - int fd; - - for (fd = 0; fd < keep_fd; fd++) - close(fd); - - close_all_beyond(keep_fd); -} - - -/* - * close_all_beyond() - * - * Close all file descriptors after the given keep_fd, which is the - * highest fd to keep open. - */ -void -close_all_beyond( - int keep_fd - ) -{ -# ifdef HAVE_CLOSEFROM - closefrom(keep_fd + 1); -# elif defined(F_CLOSEM) - /* - * From 'Writing Reliable AIX Daemons,' SG24-4946-00, - * by Eric Agar (saves us from doing 32767 system - * calls) - */ - if (fcntl(keep_fd + 1, F_CLOSEM, 0) == -1) - msyslog(LOG_ERR, "F_CLOSEM(%d): %m", keep_fd + 1); -# else /* !HAVE_CLOSEFROM && !F_CLOSEM follows */ - int fd; - int max_fd; - - max_fd = GETDTABLESIZE(); - for (fd = keep_fd + 1; fd < max_fd; fd++) - close(fd); -# endif /* !HAVE_CLOSEFROM && !F_CLOSEM */ -} -#endif /* HAVE_IO_COMPLETION_PORT */ - - #ifdef DEBUG_TIMING /* * collect timing information for various processing @@ -591,6 +403,10 @@ init_io(void) /* update interface every 5 minutes as default */ interface_interval = 300; +#ifdef WORK_PIPE + addremove_io_fd = &ntpd_addremove_io_fd; +#endif + #ifdef SYS_WINNT init_io_completion_port(); #endif @@ -601,6 +417,18 @@ init_io(void) } +void +ntpd_addremove_io_fd( + int fd, + int is_pipe, + int remove_it + ) +{ + UNUSED_ARG(is_pipe); + maintain_activefds(fd, remove_it); +} + + /* * io_open_sockets - call socket creation routine */ @@ -3276,7 +3104,7 @@ read_refclock_packet(SOCKET fd, struct refclockio *rp, l_fp ts) * put it on the full list and do bookkeeping. */ rb->recv_length = buflen; - rb->recv_srcclock = rp->srcclock; + rb->recv_peer = rp->srcclock; rb->dstadr = 0; rb->fd = fd; rb->recv_time = ts; @@ -3481,22 +3309,24 @@ read_network_packet( */ void input_handler( - l_fp *cts + l_fp * cts ) { - int buflen; - int n; - int doing; - SOCKET fd; - struct timeval tvzero; - l_fp ts; /* Timestamp at BOselect() gob */ + int buflen; + int n; + u_int idx; + int doing; + SOCKET fd; + blocking_child *c; + struct timeval tvzero; + l_fp ts; /* Timestamp at BOselect() gob */ #ifdef DEBUG_TIMING - l_fp ts_e; /* Timestamp at EOselect() gob */ + l_fp ts_e; /* Timestamp at EOselect() gob */ #endif - fd_set fds; - size_t select_count; - endpt *ep; -#if defined(HAS_ROUTING_SOCKET) + fd_set fds; + size_t select_count; + endpt * ep; +#ifdef HAS_ROUTING_SOCKET struct asyncio_reader *asyncio_reader; #endif @@ -3617,19 +3447,20 @@ input_handler( #endif /* HAS_ROUTING_SOCKET */ /* - * Check for a response from the blocking child + * Check for a response from a blocking child */ - if (parent_resp_read_pipe && - FD_ISSET(parent_resp_read_pipe, &fds)) { - select_count++; - process_blocking_response(); + for (idx = 0; idx < blocking_children_alloc; idx++) { + c = blocking_children[idx]; + if (NULL == c || -1 == c->resp_read_pipe) + continue; + if (FD_ISSET(c->resp_read_pipe, &fds)) { + select_count++; + process_blocking_resp(c); + } } /* * Done everything from that select. - */ - - /* * If nothing to do, just return. * If an error occurred, complain and return. */ @@ -4150,7 +3981,9 @@ io_closeclock( */ #ifndef SYS_WINNT void -kill_asyncio(int startfd) +kill_asyncio( + int startfd + ) { BLOCKIO(); @@ -4368,7 +4201,7 @@ process_routing_msgs(struct asyncio_reader *reader) #ifdef HAVE_RTNETLINK struct nlmsghdr *nh; #else - struct rt_msghdr *rtm; + struct rt_msghdr rtm; char *p; #endif @@ -4403,18 +4236,18 @@ process_routing_msgs(struct asyncio_reader *reader) #else for (p = buffer; (p + sizeof(struct rt_msghdr)) <= (buffer + cnt); - p += rtm->rtm_msglen) { - rtm = (struct rt_msghdr *)p; - if (rtm->rtm_version != RTM_VERSION) { + p += rtm.rtm_msglen) { + memcpy(&rtm, p, sizeof(rtm)); + if (rtm.rtm_version != RTM_VERSION) { msyslog(LOG_ERR, "version mismatch (got %d - expected %d) on routing socket - disabling", - rtm->rtm_version, RTM_VERSION); + rtm.rtm_version, RTM_VERSION); remove_asyncio_reader(reader); delete_asyncio_reader(reader); return; } - msg_type = rtm->rtm_type; + msg_type = rtm.rtm_type; #endif switch (msg_type) { #ifdef RTM_NEWADDR diff --git a/ntpd/ntp_request.c b/ntpd/ntp_request.c index e86d3a433..2b9b68d2b 100644 --- a/ntpd/ntp_request.c +++ b/ntpd/ntp_request.c @@ -50,7 +50,7 @@ struct req_proc { short needs_auth; /* true when authentication needed */ short sizeofitem; /* size of request data item (older size)*/ short v6_sizeofitem; /* size of request data item (new size)*/ - void (*handler) (sockaddr_u *, struct interface *, + void (*handler) (sockaddr_u *, endpt *, struct req_pkt *); /* routine to handle request */ }; @@ -61,60 +61,60 @@ static const struct req_proc univ_codes[] = { { NO_REQUEST, NOAUTH, 0, 0 } }; -static void req_ack (sockaddr_u *, struct interface *, struct req_pkt *, int); -static char * prepare_pkt (sockaddr_u *, struct interface *, +static void req_ack (sockaddr_u *, endpt *, struct req_pkt *, int); +static void * prepare_pkt (sockaddr_u *, endpt *, struct req_pkt *, size_t); -static char * more_pkt (void); +static void * more_pkt (void); static void flush_pkt (void); -static void list_peers (sockaddr_u *, struct interface *, struct req_pkt *); -static void list_peers_sum (sockaddr_u *, struct interface *, struct req_pkt *); -static void peer_info (sockaddr_u *, struct interface *, struct req_pkt *); -static void peer_stats (sockaddr_u *, struct interface *, struct req_pkt *); -static void sys_info (sockaddr_u *, struct interface *, struct req_pkt *); -static void sys_stats (sockaddr_u *, struct interface *, struct req_pkt *); -static void mem_stats (sockaddr_u *, struct interface *, struct req_pkt *); -static void io_stats (sockaddr_u *, struct interface *, struct req_pkt *); -static void timer_stats (sockaddr_u *, struct interface *, struct req_pkt *); -static void loop_info (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_conf (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_unconf (sockaddr_u *, struct interface *, struct req_pkt *); -static void set_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); -static void clr_sys_flag (sockaddr_u *, struct interface *, struct req_pkt *); -static void setclr_flags (sockaddr_u *, struct interface *, struct req_pkt *, u_long); +static void list_peers (sockaddr_u *, endpt *, struct req_pkt *); +static void list_peers_sum (sockaddr_u *, endpt *, struct req_pkt *); +static void peer_info (sockaddr_u *, endpt *, struct req_pkt *); +static void peer_stats (sockaddr_u *, endpt *, struct req_pkt *); +static void sys_info (sockaddr_u *, endpt *, struct req_pkt *); +static void sys_stats (sockaddr_u *, endpt *, struct req_pkt *); +static void mem_stats (sockaddr_u *, endpt *, struct req_pkt *); +static void io_stats (sockaddr_u *, endpt *, struct req_pkt *); +static void timer_stats (sockaddr_u *, endpt *, struct req_pkt *); +static void loop_info (sockaddr_u *, endpt *, struct req_pkt *); +static void do_conf (sockaddr_u *, endpt *, struct req_pkt *); +static void do_unconf (sockaddr_u *, endpt *, struct req_pkt *); +static void set_sys_flag (sockaddr_u *, endpt *, struct req_pkt *); +static void clr_sys_flag (sockaddr_u *, endpt *, struct req_pkt *); +static void setclr_flags (sockaddr_u *, endpt *, struct req_pkt *, u_long); static void list_restrict4 (restrict_u *, struct info_restrict **); static void list_restrict6 (restrict_u *, struct info_restrict **); -static void list_restrict (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_resaddflags (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_ressubflags (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_unrestrict (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_restrict (sockaddr_u *, struct interface *, struct req_pkt *, int); -static void mon_getlist (sockaddr_u *, struct interface *, struct req_pkt *); -static void reset_stats (sockaddr_u *, struct interface *, struct req_pkt *); -static void reset_peer (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_key_reread (sockaddr_u *, struct interface *, struct req_pkt *); -static void trust_key (sockaddr_u *, struct interface *, struct req_pkt *); -static void untrust_key (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_trustkey (sockaddr_u *, struct interface *, struct req_pkt *, u_long); -static void get_auth_info (sockaddr_u *, struct interface *, struct req_pkt *); +static void list_restrict (sockaddr_u *, endpt *, struct req_pkt *); +static void do_resaddflags (sockaddr_u *, endpt *, struct req_pkt *); +static void do_ressubflags (sockaddr_u *, endpt *, struct req_pkt *); +static void do_unrestrict (sockaddr_u *, endpt *, struct req_pkt *); +static void do_restrict (sockaddr_u *, endpt *, struct req_pkt *, int); +static void mon_getlist (sockaddr_u *, endpt *, struct req_pkt *); +static void reset_stats (sockaddr_u *, endpt *, struct req_pkt *); +static void reset_peer (sockaddr_u *, endpt *, struct req_pkt *); +static void do_key_reread (sockaddr_u *, endpt *, struct req_pkt *); +static void trust_key (sockaddr_u *, endpt *, struct req_pkt *); +static void untrust_key (sockaddr_u *, endpt *, struct req_pkt *); +static void do_trustkey (sockaddr_u *, endpt *, struct req_pkt *, u_long); +static void get_auth_info (sockaddr_u *, endpt *, struct req_pkt *); static void reset_auth_stats (void); -static void req_get_traps (sockaddr_u *, struct interface *, struct req_pkt *); -static void req_set_trap (sockaddr_u *, struct interface *, struct req_pkt *); -static void req_clr_trap (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_setclr_trap (sockaddr_u *, struct interface *, struct req_pkt *, int); -static void set_request_keyid (sockaddr_u *, struct interface *, struct req_pkt *); -static void set_control_keyid (sockaddr_u *, struct interface *, struct req_pkt *); -static void get_ctl_stats (sockaddr_u *, struct interface *, struct req_pkt *); -static void get_if_stats (sockaddr_u *, struct interface *, struct req_pkt *); -static void do_if_reload (sockaddr_u *, struct interface *, struct req_pkt *); +static void req_get_traps (sockaddr_u *, endpt *, struct req_pkt *); +static void req_set_trap (sockaddr_u *, endpt *, struct req_pkt *); +static void req_clr_trap (sockaddr_u *, endpt *, struct req_pkt *); +static void do_setclr_trap (sockaddr_u *, endpt *, struct req_pkt *, int); +static void set_request_keyid (sockaddr_u *, endpt *, struct req_pkt *); +static void set_control_keyid (sockaddr_u *, endpt *, struct req_pkt *); +static void get_ctl_stats (sockaddr_u *, endpt *, struct req_pkt *); +static void get_if_stats (sockaddr_u *, endpt *, struct req_pkt *); +static void do_if_reload (sockaddr_u *, endpt *, struct req_pkt *); #ifdef KERNEL_PLL -static void get_kernel_info (sockaddr_u *, struct interface *, struct req_pkt *); +static void get_kernel_info (sockaddr_u *, endpt *, struct req_pkt *); #endif /* KERNEL_PLL */ #ifdef REFCLOCK -static void get_clock_info (sockaddr_u *, struct interface *, struct req_pkt *); -static void set_clock_fudge (sockaddr_u *, struct interface *, struct req_pkt *); +static void get_clock_info (sockaddr_u *, endpt *, struct req_pkt *); +static void set_clock_fudge (sockaddr_u *, endpt *, struct req_pkt *); #endif /* REFCLOCK */ #ifdef REFCLOCK -static void get_clkbug_info (sockaddr_u *, struct interface *, struct req_pkt *); +static void get_clkbug_info (sockaddr_u *, endpt *, struct req_pkt *); #endif /* REFCLOCK */ /* @@ -222,7 +222,7 @@ static int databytes; static char exbuf[RESP_DATA_SIZE]; static int usingexbuf; static sockaddr_u *toaddr; -static struct interface *frominter; +static endpt *frominter; /* * init_request - initialize request data @@ -248,7 +248,7 @@ init_request (void) static void req_ack( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt, int errcode ) @@ -275,10 +275,10 @@ req_ack( * prepare_pkt - prepare response packet for transmission, return pointer * to storage for data item. */ -static char * +static void * prepare_pkt( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *pkt, size_t structsize ) @@ -307,14 +307,14 @@ prepare_pkt( /* * return the beginning of the packet buffer. */ - return &rpkt.data[0]; + return &rpkt.u; } /* * more_pkt - return a data pointer for a new item. */ -static char * +static void * more_pkt(void) { /* @@ -332,7 +332,7 @@ more_pkt(void) /* * Copy data out of exbuf into the packet. */ - memcpy(&rpkt.data[0], exbuf, (unsigned)itemsize); + memcpy(&rpkt.u.data[0], exbuf, (unsigned)itemsize); seqno++; databytes = 0; nitems = 0; @@ -347,7 +347,7 @@ more_pkt(void) * More room in packet. Give him the * next address. */ - return &rpkt.data[databytes]; + return &rpkt.u.data[databytes]; } else { /* * No room in packet. Give him the extra @@ -414,7 +414,7 @@ process_private( struct req_pkt *inpkt; struct req_pkt_tail *tailinpkt; sockaddr_u *srcadr; - struct interface *inter; + endpt *inter; const struct req_proc *proc; int ec; short temp_size; @@ -660,13 +660,13 @@ process_private( static void list_peers( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { - register struct info_peer_list *ip; - register struct peer *pp; - register int skip = 0; + struct info_peer_list *ip; + struct peer *pp; + int skip = 0; ip = (struct info_peer_list *)prepare_pkt(srcadr, inter, inpkt, v6sizeof(struct info_peer_list)); @@ -713,7 +713,7 @@ list_peers( static void list_peers_sum( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -808,37 +808,47 @@ list_peers_sum( static void peer_info ( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { - register struct info_peer_list *ipl; - register struct peer *pp; - register struct info_peer *ip; - register int items; - register int i, j; - sockaddr_u addr; - l_fp ltmp; + u_short items; + size_t item_sz; + char * datap; + struct info_peer_list ipl; + struct peer * pp; + struct info_peer * ip; + int i; + int j; + sockaddr_u addr; + l_fp ltmp; items = INFO_NITEMS(inpkt->err_nitems); - ipl = (struct info_peer_list *) inpkt->data; - - ip = (struct info_peer *)prepare_pkt(srcadr, inter, inpkt, - v6sizeof(struct info_peer)); - while (items-- > 0 && ip != 0) { + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->u.data; + if (item_sz != sizeof(ipl)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } + ip = prepare_pkt(srcadr, inter, inpkt, + v6sizeof(struct info_peer)); + while (items-- > 0 && ip != NULL) { + ZERO(ipl); + memcpy(&ipl, datap, item_sz); ZERO_SOCK(&addr); - NSRCPORT(&addr) = ipl->port; - if (client_v6_capable && ipl->v6_flag) { + NSRCPORT(&addr) = ipl.port; + if (client_v6_capable && ipl.v6_flag) { AF(&addr) = AF_INET6; - SOCK_ADDR6(&addr) = ipl->addr6; + SOCK_ADDR6(&addr) = ipl.addr6; } else { AF(&addr) = AF_INET; - NSRCADR(&addr) = ipl->addr; + NSRCADR(&addr) = ipl.addr; } #ifdef ISC_PLATFORM_HAVESALEN addr.sa.sa_len = SOCKLEN(&addr); #endif - ipl++; + datap += item_sz; + if ((pp = findexistingpeer(&addr, NULL, NULL, -1)) == 0) continue; if (IS_IPV6(srcadr)) { @@ -875,19 +885,19 @@ peer_info ( ip->srcport = NSRCPORT(&pp->srcadr); ip->flags = 0; if (pp == sys_peer) - ip->flags |= INFO_FLAG_SYSPEER; + ip->flags |= INFO_FLAG_SYSPEER; if (pp->flags & FLAG_CONFIG) - ip->flags |= INFO_FLAG_CONFIG; + ip->flags |= INFO_FLAG_CONFIG; if (pp->flags & FLAG_REFCLOCK) - ip->flags |= INFO_FLAG_REFCLOCK; + ip->flags |= INFO_FLAG_REFCLOCK; if (pp->flags & FLAG_PREFER) - ip->flags |= INFO_FLAG_PREFER; + ip->flags |= INFO_FLAG_PREFER; if (pp->flags & FLAG_BURST) - ip->flags |= INFO_FLAG_BURST; + ip->flags |= INFO_FLAG_BURST; if (pp->status == CTL_PST_SEL_SYNCCAND) - ip->flags |= INFO_FLAG_SEL_CANDIDATE; + ip->flags |= INFO_FLAG_SEL_CANDIDATE; if (pp->status >= CTL_PST_SEL_SYSPEER) - ip->flags |= INFO_FLAG_SHORTLIST; + ip->flags |= INFO_FLAG_SHORTLIST; ip->leap = pp->leap; ip->hmode = pp->hmode; ip->keyid = pp->keyid; @@ -897,9 +907,9 @@ peer_info ( ip->precision = pp->precision; ip->version = pp->version; ip->reach = pp->reach; - ip->unreach = (u_char) pp->unreach; + ip->unreach = (u_char)pp->unreach; ip->flash = (u_char)pp->flash; - ip->flash2 = (u_short) pp->flash; + ip->flash2 = (u_short)pp->flash; ip->estbdelay = HTONS_FP(DTOFP(pp->delay)); ip->ttl = pp->ttl; ip->associd = htons(pp->associd); @@ -913,21 +923,22 @@ peer_info ( j = pp->filter_nextpt - 1; for (i = 0; i < NTP_SHIFT; i++, j--) { if (j < 0) - j = NTP_SHIFT-1; + j = NTP_SHIFT-1; ip->filtdelay[i] = HTONS_FP(DTOFP(pp->filter_delay[j])); DTOLFP(pp->filter_offset[j], <mp); HTONL_FP(<mp, &ip->filtoffset[i]); - ip->order[i] = (u_char)((pp->filter_nextpt+NTP_SHIFT-1) - - pp->filter_order[i]); + ip->order[i] = (u_char)((pp->filter_nextpt + + NTP_SHIFT - 1) - + pp->filter_order[i]); if (ip->order[i] >= NTP_SHIFT) - ip->order[i] -= NTP_SHIFT; + ip->order[i] -= NTP_SHIFT; } DTOLFP(pp->offset, <mp); HTONL_FP(<mp, &ip->offset); ip->delay = HTONS_FP(DTOFP(pp->delay)); ip->dispersion = HTONS_FP(DTOUFP(SQRT(pp->disp))); ip->selectdisp = HTONS_FP(DTOUFP(SQRT(pp->jitter))); - ip = (struct info_peer *)more_pkt(); + ip = more_pkt(); } flush_pkt(); } @@ -939,42 +950,47 @@ peer_info ( static void peer_stats ( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { - register struct info_peer_list *ipl; - register struct peer *pp; - register struct info_peer_stats *ip; - register int items; + u_short items; + size_t item_sz; + char * datap; + struct info_peer_list ipl; + struct peer * pp; + struct info_peer_stats *ip; sockaddr_u addr; -#ifdef DEBUG - if (debug) - printf("peer_stats: called\n"); -#endif + DPRINTF(1, ("peer_stats: called\n")); items = INFO_NITEMS(inpkt->err_nitems); - ipl = (struct info_peer_list *) inpkt->data; - ip = (struct info_peer_stats *)prepare_pkt(srcadr, inter, inpkt, - v6sizeof(struct info_peer_stats)); - while (items-- > 0 && ip != 0) { + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->u.data; + if (item_sz > sizeof(ipl)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } + ip = prepare_pkt(srcadr, inter, inpkt, + v6sizeof(struct info_peer_stats)); + while (items-- > 0 && ip != NULL) { + ZERO(ipl); + memcpy(&ipl, datap, item_sz); ZERO(addr); - NSRCPORT(&addr) = ipl->port; - if (client_v6_capable && ipl->v6_flag) { + NSRCPORT(&addr) = ipl.port; + if (client_v6_capable && ipl.v6_flag) { AF(&addr) = AF_INET6; - SOCK_ADDR6(&addr) = ipl->addr6; + SOCK_ADDR6(&addr) = ipl.addr6; } else { AF(&addr) = AF_INET; - NSRCADR(&addr) = ipl->addr; + NSRCADR(&addr) = ipl.addr; } #ifdef ISC_PLATFORM_HAVESALEN addr.sa.sa_len = SOCKLEN(&addr); #endif DPRINTF(1, ("peer_stats: looking for %s, %d, %d\n", - stoa(&addr), ipl->port, NSRCPORT(&addr))); + stoa(&addr), ipl.port, NSRCPORT(&addr))); - ipl = (struct info_peer_list *)((char *)ipl + - INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; if ((pp = findexistingpeer(&addr, NULL, NULL, -1)) == NULL) continue; @@ -1054,7 +1070,7 @@ peer_stats ( static void sys_info( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1125,7 +1141,7 @@ sys_info( static void sys_stats( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1155,7 +1171,7 @@ sys_stats( static void mem_stats( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1187,11 +1203,11 @@ mem_stats( static void io_stats( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { - register struct info_io_stats *io; + struct info_io_stats *io; io = (struct info_io_stats *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_io_stats)); @@ -1220,7 +1236,7 @@ io_stats( static void timer_stats( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1245,11 +1261,11 @@ timer_stats( static void loop_info( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { - register struct info_loop *li; + struct info_loop *li; l_fp ltmp; li = (struct info_loop *)prepare_pkt(srcadr, inter, inpkt, @@ -1262,7 +1278,7 @@ loop_info( li->compliance = htonl((u_int32)(tc_counter)); li->watchdog_timer = htonl((u_int32)(current_time - sys_epoch)); - (void) more_pkt(); + more_pkt(); flush_pkt(); } @@ -1273,15 +1289,16 @@ loop_info( static void do_conf( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { - int items; - u_int fl; - struct conf_peer *cp; - struct conf_peer temp_cp; - sockaddr_u peeraddr; + u_short items; + size_t item_sz; + u_int fl; + char * datap; + struct conf_peer temp_cp; + sockaddr_u peeraddr; /* * Do a check of everything to see that it looks @@ -1289,19 +1306,16 @@ do_conf( * very picky here. */ items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_peer *)inpkt->data; - ZERO(temp_cp); - memcpy(&temp_cp, (void *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); - - /* - * Looks okay, try it out - */ - items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_peer *)inpkt->data; + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->u.data; + if (item_sz > sizeof(temp_cp)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } while (items-- > 0) { ZERO(temp_cp); - memcpy(&temp_cp, (char *)cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); + memcpy(&temp_cp, datap, item_sz); ZERO_SOCK(&peeraddr); fl = 0; @@ -1315,7 +1329,7 @@ do_conf( if (temp_cp.flags & CONF_FLAG_SKEY) fl |= FLAG_SKEY; #endif /* AUTOKEY */ - if (client_v6_capable && temp_cp.v6_flag != 0) { + if (client_v6_capable && temp_cp.v6_flag) { AF(&peeraddr) = AF_INET6; SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; } else { @@ -1345,118 +1359,30 @@ do_conf( return; } - cp = (struct conf_peer *) - ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } - req_ack(srcadr, inter, inpkt, INFO_OKAY); } -#if 0 -/* XXX */ -/* - * dns_a - Snarf DNS info for an association ID - */ -static void -dns_a( - sockaddr_u *srcadr, - struct interface *inter, - struct req_pkt *inpkt - ) -{ - register struct info_dns_assoc *dp; - register int items; - struct sockaddr_in peeraddr; - - /* - * Do a check of everything to see that it looks - * okay. If not, complain about it. Note we are - * very picky here. - */ - items = INFO_NITEMS(inpkt->err_nitems); - dp = (struct info_dns_assoc *)inpkt->data; - - /* - * Looks okay, try it out - */ - items = INFO_NITEMS(inpkt->err_nitems); - dp = (struct info_dns_assoc *)inpkt->data; - ZERO(peeraddr); - peeraddr.sin_family = AF_INET; - peeraddr.sin_port = htons(NTP_PORT); - - /* - * Make sure the address is valid - */ - if (!ISREFCLOCKADR(&peeraddr) && ISBADADR(&peeraddr)) { - msyslog(LOG_ERR, "dns_a: !ISREFCLOCKADR && ISBADADR"); - req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); - return; - } - - while (items-- > 0) { - associd_t associd; - size_t hnl; - struct peer *peer; - int bogon = 0; - - associd = dp->associd; - peer = findpeerbyassoc(associd); - if (peer == 0 || peer->flags & FLAG_REFCLOCK) { - msyslog(LOG_ERR, "dns_a: %s", - (peer == 0) - ? "peer == 0" - : "peer->flags & FLAG_REFCLOCK"); - ++bogon; - } - peeraddr.sin_addr.s_addr = dp->peeraddr; - for (hnl = 0; dp->hostname[hnl] && hnl < sizeof dp->hostname; ++hnl) ; - if (hnl >= sizeof dp->hostname) { - msyslog(LOG_ERR, "dns_a: hnl (%ld) >= %ld", - (long)hnl, (long)sizeof dp->hostname); - ++bogon; - } - - msyslog(LOG_INFO, "dns_a: <%s> for %s, AssocID %d, bogon %d", - dp->hostname, - stoa((sockaddr_u *)&peeraddr), associd, - bogon); - - if (bogon) { - /* If it didn't work */ - req_ack(srcadr, inter, inpkt, INFO_ERR_NODATA); - return; - } else { -#if 0 -#ifdef PUBKEY - crypto_public(peer, dp->hostname); -#endif /* PUBKEY */ -#endif - } - - dp++; - } - - req_ack(srcadr, inter, inpkt, INFO_OKAY); -} -#endif /* 0 */ /* * do_unconf - remove a peer from the configuration list */ static void do_unconf( - sockaddr_u *srcadr, - struct interface *inter, + sockaddr_u * srcadr, + endpt * inter, struct req_pkt *inpkt ) { - register struct conf_unpeer *cp; - struct conf_unpeer temp_cp; - register int items; - register struct peer *peer; - sockaddr_u peeraddr; - int bad, found; + u_short items; + size_t item_sz; + char * datap; + struct conf_unpeer temp_cp; + struct peer * p; + sockaddr_u peeraddr; + int bad; + int found; /* * This is a bit unstructured, but I like to be careful. @@ -1465,13 +1391,18 @@ do_unconf( * an error. */ items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_unpeer *)inpkt->data; + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->u.data; + if (item_sz > sizeof(temp_cp)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } - bad = 0; + bad = FALSE; while (items-- > 0 && !bad) { ZERO(temp_cp); + memcpy(&temp_cp, datap, item_sz); ZERO_SOCK(&peeraddr); - memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); if (client_v6_capable && temp_cp.v6_flag) { AF(&peeraddr) = AF_INET6; SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; @@ -1483,22 +1414,22 @@ do_unconf( #ifdef ISC_PLATFORM_HAVESALEN peeraddr.sa.sa_len = SOCKLEN(&peeraddr); #endif - found = 0; - peer = NULL; + found = FALSE; + p = NULL; DPRINTF(1, ("searching for %s\n", stoa(&peeraddr))); while (!found) { - peer = findexistingpeer(&peeraddr, NULL, peer, -1); - if (!peer) + p = findexistingpeer(&peeraddr, NULL, p, -1); + if (NULL == p) break; - if (peer->flags & FLAG_CONFIG) - found = 1; + if (FLAG_CONFIG & p->flags) + found = TRUE; } if (!found) - bad = 1; - cp = (struct conf_unpeer *) - ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); + bad = TRUE; + + datap += item_sz; } if (bad) { @@ -1510,13 +1441,12 @@ do_unconf( * Now do it in earnest. */ - items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_unpeer *)inpkt->data; + datap = inpkt->u.data; while (items-- > 0) { ZERO(temp_cp); + memcpy(&temp_cp, datap, item_sz); ZERO(peeraddr); - memcpy(&temp_cp, cp, INFO_ITEMSIZE(inpkt->mbz_itemsize)); if (client_v6_capable && temp_cp.v6_flag) { AF(&peeraddr) = AF_INET6; SOCK_ADDR6(&peeraddr) = temp_cp.peeraddr6; @@ -1528,24 +1458,23 @@ do_unconf( #ifdef ISC_PLATFORM_HAVESALEN peeraddr.sa.sa_len = SOCKLEN(&peeraddr); #endif - found = 0; - peer = NULL; + found = FALSE; + p = NULL; while (!found) { - peer = findexistingpeer(&peeraddr, NULL, peer, -1); - if (!peer) + p = findexistingpeer(&peeraddr, NULL, p, -1); + if (NULL == p) break; - if (peer->flags & FLAG_CONFIG) - found = 1; + if (FLAG_CONFIG & p->flags) + found = TRUE; } - NTP_INSIST(found); - NTP_INSIST(peer); + INSIST(found); + INSIST(NULL != p); - peer_clear(peer, "GONE"); - unpeer(peer); + peer_clear(p, "GONE"); + unpeer(p); - cp = (struct conf_unpeer *) - ((char *)cp + INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } req_ack(srcadr, inter, inpkt, INFO_OKAY); @@ -1558,7 +1487,7 @@ do_unconf( static void set_sys_flag( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1572,7 +1501,7 @@ set_sys_flag( static void clr_sys_flag( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1586,7 +1515,7 @@ clr_sys_flag( static void setclr_flags( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt, u_long set ) @@ -1600,7 +1529,7 @@ setclr_flags( return; } - sf = (struct conf_sys_flags *)inpkt->data; + sf = (struct conf_sys_flags *)&inpkt->u; flags = ntohl(sf->flags); if (flags & ~(SYS_FLAG_BCLIENT | SYS_FLAG_PPS | @@ -1693,7 +1622,7 @@ list_restrict6( static void list_restrict( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1723,7 +1652,7 @@ list_restrict( static void do_resaddflags( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1738,7 +1667,7 @@ do_resaddflags( static void do_ressubflags( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1752,7 +1681,7 @@ do_ressubflags( static void do_unrestrict( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1766,16 +1695,18 @@ do_unrestrict( static void do_restrict( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt, int op ) { - register struct conf_restrict *cr; - register int items; - sockaddr_u matchaddr; - sockaddr_u matchmask; - int bad; + char * datap; + struct conf_restrict cr; + u_short items; + size_t item_sz; + sockaddr_u matchaddr; + sockaddr_u matchmask; + int bad; /* * Do a check of the flags to make sure that only @@ -1783,26 +1714,32 @@ do_restrict( * about it. Note we are very picky here. */ items = INFO_NITEMS(inpkt->err_nitems); - cr = (struct conf_restrict *)inpkt->data; + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->u.data; + if (item_sz > sizeof(cr)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } - bad = 0; - cr->flags = ntohs(cr->flags); - cr->mflags = ntohs(cr->mflags); + bad = FALSE; while (items-- > 0 && !bad) { - if (cr->mflags & ~(RESM_NTPONLY)) - bad |= 1; - if (cr->flags & ~(RES_ALLFLAGS)) - bad |= 2; - if (cr->mask != htonl(INADDR_ANY)) { - if (client_v6_capable && cr->v6_flag != 0) { - if (IN6_IS_ADDR_UNSPECIFIED(&cr->addr6)) + memcpy(&cr, datap, item_sz); + cr.flags = ntohs(cr.flags); + cr.mflags = ntohs(cr.mflags); + if (~RESM_NTPONLY & cr.mflags) + bad |= 1; + if (~RES_ALLFLAGS & cr.flags) + bad |= 2; + if (INADDR_ANY != cr.mask) { + if (client_v6_capable && cr.v6_flag) { + if (IN6_IS_ADDR_UNSPECIFIED(&cr.addr6)) bad |= 4; - } else - if (cr->addr == htonl(INADDR_ANY)) + } else { + if (INADDR_ANY == cr.addr) bad |= 8; + } } - cr = (struct conf_restrict *)((char *)cr + - INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } if (bad) { @@ -1814,26 +1751,28 @@ do_restrict( /* * Looks okay, try it out */ - items = INFO_NITEMS(inpkt->err_nitems); - cr = (struct conf_restrict *)inpkt->data; ZERO_SOCK(&matchaddr); ZERO_SOCK(&matchmask); + datap = inpkt->u.data; while (items-- > 0) { - if (client_v6_capable && cr->v6_flag) { + memcpy(&cr, datap, item_sz); + cr.flags = ntohs(cr.flags); + cr.mflags = ntohs(cr.mflags); + if (client_v6_capable && cr.v6_flag) { AF(&matchaddr) = AF_INET6; AF(&matchmask) = AF_INET6; - SOCK_ADDR6(&matchaddr) = cr->addr6; - SOCK_ADDR6(&matchmask) = cr->mask6; + SOCK_ADDR6(&matchaddr) = cr.addr6; + SOCK_ADDR6(&matchmask) = cr.mask6; } else { AF(&matchaddr) = AF_INET; AF(&matchmask) = AF_INET; - NSRCADR(&matchaddr) = cr->addr; - NSRCADR(&matchmask) = cr->mask; + NSRCADR(&matchaddr) = cr.addr; + NSRCADR(&matchmask) = cr.mask; } - hack_restrict(op, &matchaddr, &matchmask, cr->mflags, - cr->flags, 0); - cr++; + hack_restrict(op, &matchaddr, &matchmask, cr.mflags, + cr.flags, 0); + datap += item_sz; } req_ack(srcadr, inter, inpkt, INFO_OKAY); @@ -1846,7 +1785,7 @@ do_restrict( static void mon_getlist( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1879,7 +1818,7 @@ struct reset_entry reset_entries[] = { static void reset_stats( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -1893,7 +1832,7 @@ reset_stats( return; } - rflags = (struct reset_flags *)inpkt->data; + rflags = (struct reset_flags *)&inpkt->u; flags = ntohl(rflags->flags); if (flags & ~RESET_ALLFLAGS) { @@ -1917,15 +1856,17 @@ reset_stats( static void reset_peer( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { - struct conf_unpeer *cp; - int items; - struct peer *peer; - sockaddr_u peeraddr; - int bad; + u_short items; + size_t item_sz; + char * datap; + struct conf_unpeer cp; + struct peer * p; + sockaddr_u peeraddr; + int bad; /* * We check first to see that every peer exists. If not, @@ -1933,27 +1874,33 @@ reset_peer( */ items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_unpeer *)inpkt->data; + item_sz = INFO_ITEMSIZE(inpkt->mbz_itemsize); + datap = inpkt->u.data; + if (item_sz > sizeof(cp)) { + req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); + return; + } - bad = 0; + bad = FALSE; while (items-- > 0 && !bad) { + ZERO(cp); + memcpy(&cp, datap, item_sz); ZERO_SOCK(&peeraddr); - if (client_v6_capable && cp->v6_flag) { + if (client_v6_capable && cp.v6_flag) { AF(&peeraddr) = AF_INET6; - SOCK_ADDR6(&peeraddr) = cp->peeraddr6; + SOCK_ADDR6(&peeraddr) = cp.peeraddr6; } else { AF(&peeraddr) = AF_INET; - NSRCADR(&peeraddr) = cp->peeraddr; + NSRCADR(&peeraddr) = cp.peeraddr; } #ifdef ISC_PLATFORM_HAVESALEN peeraddr.sa.sa_len = SOCKLEN(&peeraddr); #endif - peer = findexistingpeer(&peeraddr, NULL, NULL, -1); - if (NULL == peer) + p = findexistingpeer(&peeraddr, NULL, NULL, -1); + if (NULL == p) bad++; - cp = (struct conf_unpeer *)((char *)cp + - INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } if (bad) { @@ -1965,28 +1912,28 @@ reset_peer( * Now do it in earnest. */ - items = INFO_NITEMS(inpkt->err_nitems); - cp = (struct conf_unpeer *)inpkt->data; + datap = inpkt->u.data; while (items-- > 0) { + ZERO(cp); + memcpy(&cp, datap, item_sz); ZERO_SOCK(&peeraddr); - if (client_v6_capable && cp->v6_flag) { + if (client_v6_capable && cp.v6_flag) { AF(&peeraddr) = AF_INET6; - SOCK_ADDR6(&peeraddr) = cp->peeraddr6; + SOCK_ADDR6(&peeraddr) = cp.peeraddr6; } else { AF(&peeraddr) = AF_INET; - NSRCADR(&peeraddr) = cp->peeraddr; + NSRCADR(&peeraddr) = cp.peeraddr; } SET_PORT(&peeraddr, 123); #ifdef ISC_PLATFORM_HAVESALEN peeraddr.sa.sa_len = SOCKLEN(&peeraddr); #endif - peer = findexistingpeer(&peeraddr, NULL, NULL, -1); - while (peer != NULL) { - peer_reset(peer); - peer = findexistingpeer(&peeraddr, NULL, peer, -1); + p = findexistingpeer(&peeraddr, NULL, NULL, -1); + while (p != NULL) { + peer_reset(p); + p = findexistingpeer(&peeraddr, NULL, p, -1); } - cp = (struct conf_unpeer *)((char *)cp + - INFO_ITEMSIZE(inpkt->mbz_itemsize)); + datap += item_sz; } req_ack(srcadr, inter, inpkt, INFO_OKAY); @@ -1999,7 +1946,7 @@ reset_peer( static void do_key_reread( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2014,7 +1961,7 @@ do_key_reread( static void trust_key( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2028,7 +1975,7 @@ trust_key( static void untrust_key( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2042,7 +1989,7 @@ untrust_key( static void do_trustkey( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt, u_long trust ) @@ -2051,7 +1998,7 @@ do_trustkey( register int items; items = INFO_NITEMS(inpkt->err_nitems); - kp = (u_long *)inpkt->data; + kp = (u_long *)&inpkt->u; while (items-- > 0) { authtrust(*kp, trust); kp++; @@ -2067,7 +2014,7 @@ do_trustkey( static void get_auth_info( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2114,7 +2061,7 @@ reset_auth_stats(void) static void req_get_traps( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2168,7 +2115,7 @@ req_get_traps( static void req_set_trap( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2183,7 +2130,7 @@ req_set_trap( static void req_clr_trap( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2198,13 +2145,13 @@ req_clr_trap( static void do_setclr_trap( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt, int set ) { register struct conf_trap *ct; - register struct interface *linter; + register endpt *linter; int res; sockaddr_u laddr; @@ -2224,7 +2171,7 @@ do_setclr_trap( req_ack(srcadr, inter, inpkt, INFO_ERR_FMT); return; } - ct = (struct conf_trap *)inpkt->data; + ct = (struct conf_trap *)&inpkt->u; /* * Look for the local interface. If none, use the default. @@ -2275,7 +2222,7 @@ do_setclr_trap( static void set_request_keyid( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2290,7 +2237,7 @@ set_request_keyid( return; } - pkeyid = (keyid_t *)inpkt->data; + pkeyid = (keyid_t *)&inpkt->u; info_auth_keyid = ntohl(*pkeyid); req_ack(srcadr, inter, inpkt, INFO_OKAY); } @@ -2303,7 +2250,7 @@ set_request_keyid( static void set_control_keyid( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2318,7 +2265,7 @@ set_control_keyid( return; } - pkeyid = (keyid_t *)inpkt->data; + pkeyid = (keyid_t *)&inpkt->u; ctl_auth_keyid = ntohl(*pkeyid); req_ack(srcadr, inter, inpkt, INFO_OKAY); } @@ -2331,7 +2278,7 @@ set_control_keyid( static void get_ctl_stats( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2368,7 +2315,7 @@ get_ctl_stats( static void get_kernel_info( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2423,7 +2370,7 @@ get_kernel_info( static void get_clock_info( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2441,7 +2388,7 @@ get_clock_info( #endif SET_PORT(&addr, NTP_PORT); items = INFO_NITEMS(inpkt->err_nitems); - clkaddr = (u_int32 *) inpkt->data; + clkaddr = &inpkt->u.u32[0]; ic = (struct info_clock *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_clock)); @@ -2490,7 +2437,7 @@ get_clock_info( static void set_clock_fudge( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2503,7 +2450,7 @@ set_clock_fudge( ZERO(addr); ZERO(clock_stat); items = INFO_NITEMS(inpkt->err_nitems); - cf = (struct conf_fudge *) inpkt->data; + cf = (struct conf_fudge *)&inpkt->u; while (items-- > 0) { AF(&addr) = AF_INET; @@ -2562,7 +2509,7 @@ set_clock_fudge( static void get_clkbug_info( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2580,7 +2527,7 @@ get_clkbug_info( #endif SET_PORT(&addr, NTP_PORT); items = INFO_NITEMS(inpkt->err_nitems); - clkaddr = (u_int32 *) inpkt->data; + clkaddr = (u_int32 *)&inpkt->u; ic = (struct info_clkbug *)prepare_pkt(srcadr, inter, inpkt, sizeof(struct info_clkbug)); @@ -2660,7 +2607,7 @@ fill_info_if_stats(void *data, interface_info_t *interface_info) ifs->sent = htonl(ep->sent); ifs->notsent = htonl(ep->notsent); ifs->ifindex = htonl(ep->ifindex); - /* scope no longer in struct interface, in in6_addr typically */ + /* scope no longer in endpt, in in6_addr typically */ ifs->scopeid = ifs->ifindex; ifs->ifnum = htonl(ep->ifnum); ifs->uptime = htonl(current_time - ep->starttime); @@ -2677,7 +2624,7 @@ fill_info_if_stats(void *data, interface_info_t *interface_info) static void get_if_stats( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { @@ -2696,7 +2643,7 @@ get_if_stats( static void do_if_reload( sockaddr_u *srcadr, - struct interface *inter, + endpt *inter, struct req_pkt *inpkt ) { diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index 2a93dc90f..485d3778a 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -63,8 +63,8 @@ static u_long interface_timer; /* interface update timer */ static u_long adjust_timer; /* second timer */ static u_long stats_timer; /* stats timer */ static u_long huffpuff_timer; /* huff-n'-puff timer */ +static u_long worker_idle_timer;/* next check for idle intres */ u_long leapsec; /* leapseconds countdown */ -u_long worker_idle_timer; /* next check for idle intres */ u_long orphwait; /* orphan wait time */ #ifdef AUTOKEY static u_long revoke_timer; /* keys revoke timer */ @@ -96,8 +96,8 @@ static int vmstimer[2]; /* time for next timer AST */ static int vmsinc[2]; /* timer increment */ #endif /* VMS */ -#if defined SYS_WINNT -static HANDLE WaitableTimerHandle = NULL; +#ifdef SYS_WINNT +HANDLE WaitableTimerHandle; #else static RETSIGTYPE alarming (int); #endif /* SYS_WINNT */ @@ -186,7 +186,7 @@ init_timer(void) fprintf (stderr, "timer create FAILED\n"); exit (0); } - (void) signal_no_reset(SIGALRM, alarming); + signal_no_reset(SIGALRM, alarming); itimer.it_interval.tv_sec = itimer.it_value.tv_sec = (1< -#include "ntp_workimpl.h" - -#ifdef WORKER - -#include -#include -#include - -#include "iosignal.h" -#include "ntp_stdlib.h" -#include "ntp_malloc.h" -#include "ntp_syslog.h" -#include "ntpd.h" -#include "ntp_io.h" -#include "ntp_assert.h" -#include "ntp_unixtime.h" -#include "ntp_intres.h" - - -#define CHILD_MAX_IDLE (3 * 60) /* seconds, idle worker limit */ - -int intres_req_pending; - - -int -queue_blocking_request( - blocking_work_req rtype, - void * req, - size_t reqsize, - blocking_work_callback done_func, - void * context - ) -{ - blocking_pipe_header req_hdr; - - req_hdr.octets = sizeof(req_hdr) + reqsize; - req_hdr.magic_sig = BLOCKING_REQ_MAGIC; - req_hdr.rtype = rtype; - req_hdr.done_func = done_func; - req_hdr.context = context; - - if (0 == intres_req_pending) - worker_idle_timer = 0; - intres_req_pending++; - - return send_blocking_req_internal(&req_hdr, req); -} - -int queue_blocking_response( - blocking_pipe_header * resp, - size_t respsize, - const blocking_pipe_header * req - ) -{ - resp->octets = respsize; - resp->magic_sig = BLOCKING_RESP_MAGIC; - resp->rtype = req->rtype; - resp->context = req->context; - resp->done_func = req->done_func; - - return send_blocking_resp_internal(resp); -} - - -void -process_blocking_response( - void - ) -{ - blocking_pipe_header * resp; - void * data; - - /* - * On Windows send_blocking_resp_internal() may signal the - * blocking_response_ready event multiple times while we're - * processing a response, so always consume all available - * responses before returning to test the event again. - */ -#ifdef SYS_WINNT - do { -#endif - resp = receive_blocking_resp_internal(); - if (NULL != resp) { - NTP_REQUIRE(BLOCKING_RESP_MAGIC == resp->magic_sig); - data = (char *)resp + sizeof(*resp); - intres_req_pending--; - (*resp->done_func)(resp->rtype, resp->context, resp->octets - sizeof(*resp), data); - free(resp); - if (0 == intres_req_pending) - worker_idle_timer = current_time - + CHILD_MAX_IDLE; - } -#ifdef SYS_WINNT - } while (NULL != resp); -#endif -} - - -/* - * blocking_child_common runs as a forked child or thread - */ -int -blocking_child_common ( - void - ) -{ - int say_bye; - blocking_pipe_header *req; - - NLOG(NLOG_SYSEVENT) - msyslog(LOG_NOTICE, "DNS worker started"); - - say_bye = 0; - while (!say_bye) { - req = receive_blocking_req_internal(); - if (NULL == req) { - say_bye = 1; - break; - } - - NTP_REQUIRE(BLOCKING_REQ_MAGIC == req->magic_sig); - - switch (req->rtype) { - case BLOCKING_GETADDRINFO: - if (blocking_getaddrinfo(req)) - say_bye = 1; - break; - - case BLOCKING_GETNAMEINFO: - if (blocking_getnameinfo(req)) - say_bye = 1; - break; - - default: - msyslog(LOG_ERR, "unknown req %d to blocking worker", req->rtype); - say_bye = 1; - } - - free(req); - } - - NLOG(NLOG_SYSEVENT) - msyslog(LOG_NOTICE, "DNS worker finished"); - - return 0; -} - - -#else /* !WORKER follows */ -int ntp_worker_nonempty_compilation_unit; -#endif diff --git a/ntpd/ntpd.c b/ntpd/ntpd.c index 3ab9675ec..50fa99642 100644 --- a/ntpd/ntpd.c +++ b/ntpd/ntpd.c @@ -244,209 +244,8 @@ static void library_unexpected_error(const char *, int, const char *, va_list) ISC_FORMAT_PRINTF(3, 0); #endif /* !SIM */ -void init_logging (char const *, int); -void setup_logfile (int); -/* - * Initialize the logging - * - * Called once per process, including forked children. - */ -void -init_logging( - const char *name, - int log_version - ) -{ - const char *cp; - - /* - * ntpd defaults to only logging sync-category events, when - * NLOG() is used to conditionalize. Other libntp clients - * leave it alone so that all NLOG() conditionals will fire. - * This presumes all bits lit in ntp_syslogmask can't be - * configured via logconfig and all lit is thereby a sentinel - * that ntp_syslogmask is still at its default from libntp, - * keeping in mind this function is called in forked children - * where it has already been called in the parent earlier. - */ - if (~(u_long)0 == ntp_syslogmask) - ntp_syslogmask = NLOG_SYNCMASK; /* set more via logconfig */ - - /* - * Logging. This may actually work on the gizmo board. Find a name - * to log with by using the basename - */ - cp = strrchr(name, '/'); - if (cp == 0) - cp = name; - else - cp++; - progname = cp; - -#if !defined(VMS) - -# ifndef LOG_DAEMON - openlog(progname, LOG_PID); -# else /* LOG_DAEMON */ - -# ifndef LOG_NTP -# define LOG_NTP LOG_DAEMON -# endif - openlog(progname, LOG_PID | LOG_NDELAY, LOG_NTP); -# ifdef DEBUG - if (debug) - setlogmask(LOG_UPTO(LOG_DEBUG)); - else -# endif /* DEBUG */ - setlogmask(LOG_UPTO(LOG_DEBUG)); /* @@@ was INFO */ -# endif /* LOG_DAEMON */ -#endif /* !VMS */ - - if (log_version) - msyslog(LOG_NOTICE, "%s", Version); -} - - -/* - * change_logfile() - * - * Used to change from syslog to a logfile, or from one logfile to - * another, and to reopen logfiles after forking. On systems where - * ntpd forks, deals with converting relative logfile paths to - * absolute (root-based) because we reopen logfiles after the current - * directory has changed. - */ -int -change_logfile( - const char *fname, - int log_version - ) -{ - FILE * new_file; - const char * log_fname; - char * abs_fname; -#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS) - char curdir[512]; - size_t cd_octets; - size_t octets; -#endif /* POSIX */ - - NTP_REQUIRE(fname != NULL); - log_fname = fname; - - /* - * In a forked child of a parent which is logging to a file - * instead of syslog, syslog_file will be NULL and both - * syslog_fname and syslog_abs_fname will be non-NULL. - * If we are given the same filename previously opened - * and it's still open, there's nothing to do here. - */ - if (syslog_file != NULL && syslog_fname != NULL && - (log_fname == syslog_fname || - 0 == strcmp(syslog_fname, log_fname))) - return 0; - - if (0 == strcmp(log_fname, "stderr")) { - new_file = stderr; - abs_fname = estrdup(log_fname); - } else if (0 == strcmp(log_fname, "stdout")) { - new_file = stdout; - abs_fname = estrdup(log_fname); - } else { - if (syslog_fname != NULL && - 0 == strcmp(log_fname, syslog_fname)) - log_fname = syslog_abs_fname; -#if !defined(SYS_WINNT) && !defined(SYS_VXWORKS) && !defined(VMS) - if (log_fname != syslog_abs_fname && - DIR_SEP != log_fname[0] && - 0 != strcmp(log_fname, "stderr") && - 0 != strcmp(log_fname, "stdout") && - NULL != getcwd(curdir, sizeof(curdir))) { - cd_octets = strlen(curdir); - /* trim any trailing '/' */ - if (cd_octets > 1 && - DIR_SEP == curdir[cd_octets - 1]) - cd_octets--; - octets = cd_octets; - octets += 1; /* separator '/' */ - octets += strlen(log_fname); - octets += 1; /* NUL terminator */ - abs_fname = emalloc(octets); - snprintf(abs_fname, octets, "%.*s%c%s", - (int)cd_octets, curdir, DIR_SEP, - log_fname); - } else -#endif - abs_fname = estrdup(log_fname); - DPRINTF(1, ("attempting to open log %s", abs_fname)); - new_file = fopen(abs_fname, "a"); - } - - if (NULL == new_file) { - free(abs_fname); - return -1; - } - - /* leave a pointer in the old log */ - if (log_fname != syslog_abs_fname) - msyslog(LOG_NOTICE, "switching logging to file %s", - abs_fname); - - if (syslog_file != NULL && - syslog_file != stderr && syslog_file != stdout && - fileno(syslog_file) != fileno(new_file)) - fclose(syslog_file); - syslog_file = new_file; - if (log_fname != syslog_abs_fname) { - if (syslog_abs_fname != NULL && - syslog_abs_fname != syslog_fname) - free(syslog_abs_fname); - if (syslog_fname != NULL) - free(syslog_fname); - syslog_fname = estrdup(log_fname); - syslog_abs_fname = abs_fname; - } - syslogit = 0; - if (log_version) - msyslog(LOG_NOTICE, "%s", Version); - - return 0; -} - - -/* - * setup_logfile() - * - * Redirect logging to a file if requested with -l/--logfile or via - * ntp.conf logfile directive. - * - * This routine is invoked three different times in the sequence of a - * typical daemon ntpd with DNS lookups to do. First it is invoked in - * the original ntpd process, then again in the daemon after closing - * all descriptors. In both of those cases, ntp.conf has not been - * processed, so only -l/--logfile will trigger logfile redirection in - * those invocations. Finally, if DNS names are resolved, the worker - * child invokes this routine after its fork and close of all - * descriptors. In this case, ntp.conf has been processed and any - * "logfile" directive needs to be honored in the child as well. - */ -void -setup_logfile( - int log_version - ) -{ - if (NULL == syslog_fname && HAVE_OPT(LOGFILE)) { - if (-1 == change_logfile(OPT_ARG(LOGFILE), log_version)) - msyslog(LOG_ERR, "Cannot open log file %s, %m", - OPT_ARG(LOGFILE)); - } else if (NULL != syslog_fname) { - if (-1 == change_logfile(syslog_fname, log_version)) - msyslog(LOG_ERR, "Cannot reopen log file %s, %m", - syslog_fname); - } -} void @@ -633,40 +432,42 @@ ntpdmain( char *argv[] ) { - l_fp now; + l_fp now; struct recvbuf *rbuf; + const char * logfilename; # ifdef HAVE_UMASK - mode_t uv; + mode_t uv; # endif # if defined(HAVE_GETUID) && !defined(MPE) /* MPE lacks the concept of root */ - uid_t uid; + uid_t uid; # endif # if defined(HAVE_WORKING_FORK) - long wait_sync = 0; - int pipe_fds[2]; - int rc; - int exit_code; + long wait_sync = 0; + int pipe_fds[2]; + int rc; + int exit_code; # ifdef _AIX struct sigaction sa; # endif # if !defined(HAVE_SETSID) && !defined (HAVE_SETPGID) && defined(TIOCNOTTY) - int fid; + int fid; # endif # endif /* HAVE_WORKING_FORK*/ # ifdef SCO5_CLOCK - int fd; - int zero; + int fd; + int zero; # endif # if defined(HAVE_MLOCKALL) && defined(MCL_CURRENT) && defined(MCL_FUTURE) # ifdef HAVE_SETRLIMIT - struct rlimit rl; + struct rlimit rl; # endif # endif progname = argv[0]; - initializing = 1; /* mark that we are initializing */ + initializing = TRUE; /* mark that we are initializing */ parse_cmdline_opts(&argc, &argv); - init_logging(progname, 1); /* Open the log file */ + /* Open the log file */ + init_logging(progname, NLOG_SYNCMASK, Version, TRUE); /* * Install trap handlers to log errors and assertion failures. @@ -702,7 +503,11 @@ ntpdmain( # endif /* honor -l/--logfile option to log to a file */ - setup_logfile(1); + if (HAVE_OPT(LOGFILE)) + logfilename = OPT_ARG(LOGFILE); + else + logfilename = NULL; + setup_logfile(logfilename, Version); /* * Enable the Multi-Media Timer for Windows? @@ -716,8 +521,11 @@ ntpdmain( # ifdef DEBUG || debug # endif - || HAVE_OPT( SAVECONFIGQUIT )) + || HAVE_OPT( SAVECONFIGQUIT )) { nofork = 1; + /* duplicate all syslog to stdout */ + msyslog_term = TRUE; + } if (HAVE_OPT( NOVIRTUALIPS )) listen_to_virtual_ips = 0; @@ -821,9 +629,9 @@ ntpdmain( dup2(0, 1); dup2(0, 2); - init_logging(progname, 0); + init_logging(progname, 0, NULL, TRUE); /* we lost our logfile (if any) daemonizing */ - setup_logfile(0); + setup_logfile(logfilename, NULL); # ifdef SYS_DOMAINOS { @@ -976,6 +784,7 @@ ntpdmain( * * Exactly what command-line options are we expecting here? */ + INIT_SSL(); init_auth(); init_util(); init_restrict(); @@ -1029,11 +838,8 @@ ntpdmain( goto getuser; if ((pw = getpwuid(sw_uid)) != NULL) { - user = strdup(pw->pw_name); - if (NULL == user) { - msyslog(LOG_ERR, "strdup() failed: %m"); - exit (-1); - } + free(user); + user = estrdup(pw->pw_name); sw_gid = pw->pw_gid; } else { errno = 0; @@ -1049,9 +855,9 @@ getuser: sw_gid = pw->pw_gid; } else { if (errno) - msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user); + msyslog(LOG_ERR, "getpwnam(%s) failed: %m", user); else - msyslog(LOG_ERR, "Cannot find user `%s'", user); + msyslog(LOG_ERR, "Cannot find user `%s'", user); exit (-1); } } @@ -1133,7 +939,7 @@ getgroup: cap_t caps; char *captext; - captext = (interface_interval) + captext = (0 != interface_interval) ? "cap_sys_time,cap_net_bind_service=pe" : "cap_sys_time=pe"; caps = cap_from_text(captext); diff --git a/ntpd/refclock_acts.c b/ntpd/refclock_acts.c index 43f656240..e0a0d6dd5 100644 --- a/ntpd/refclock_acts.c +++ b/ntpd/refclock_acts.c @@ -254,13 +254,12 @@ acts_start ( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(struct actsunit)); - memset(up, 0, sizeof(struct actsunit)); + up = emalloc_zero(sizeof(struct actsunit)); up->unit = unit; pp = peer->procptr; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->io.clock_recv = acts_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = -1; @@ -298,7 +297,7 @@ acts_shutdown ( * Warning: do this only when a call is not in progress. */ pp = peer->procptr; - up = (struct actsunit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) { io_closeclock(&pp->io); pp->io.fd = -1; @@ -328,9 +327,9 @@ acts_receive ( * arbitrary fragments. Capture the timecode at the beginning of * the message and at the '*' and '#' on-time characters. */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct actsunit *)pp->unitptr; + up = pp->unitptr; refclock_gtraw(rbufp, tbuf, BMAX - (up->bufptr - up->buf), &pp->lastrec); for (tptr = tbuf; *tptr != '\0'; tptr++) { if (*tptr == LF) { @@ -376,7 +375,7 @@ acts_message( * message. */ pp = peer->procptr; - up = (struct actsunit *)pp->unitptr; + up = pp->unitptr; /* * Extract the first token in the line. @@ -475,7 +474,7 @@ acts_timeout( * when first started and at timeout. */ pp = peer->procptr; - up = (struct actsunit *)pp->unitptr; + up = pp->unitptr; switch (dstate) { /* @@ -604,7 +603,7 @@ acts_close( int dtr = TIOCM_DTR; pp = peer->procptr; - up = (struct actsunit *)pp->unitptr; + up = pp->unitptr; if (pp->io.fd != 0) { report_event(PEVNT_CLOCK, peer, "close"); ioctl(pp->io.fd, TIOCMBIC, &dtr); @@ -646,7 +645,7 @@ acts_poll( * the timeout routine and state machine. */ pp = peer->procptr; - up = (struct actsunit *)pp->unitptr; + up = pp->unitptr; switch (peer->ttl) { /* @@ -701,7 +700,7 @@ acts_timer( * called. If flag1 is set while timer is zero, force a call. */ pp = peer->procptr; - up = (struct actsunit *)pp->unitptr; + up = pp->unitptr; if (up->timer == 0) { if (pp->sloppyclockflag & CLK_FLAG1) { pp->sloppyclockflag &= ~CLK_FLAG1; @@ -751,7 +750,7 @@ acts_timecode( * errors due noise are forgivable. */ pp = peer->procptr; - up = (struct actsunit *)pp->unitptr; + up = pp->unitptr; pp->nsec = 0; switch (strlen(str)) { diff --git a/ntpd/refclock_arbiter.c b/ntpd/refclock_arbiter.c index ad42034e4..34ca9b38f 100644 --- a/ntpd/refclock_arbiter.c +++ b/ntpd/refclock_arbiter.c @@ -170,11 +170,10 @@ arb_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = arb_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -183,7 +182,7 @@ arb_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -219,7 +218,7 @@ arb_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct arbunit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -246,9 +245,9 @@ arb_receive( /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct arbunit *)pp->unitptr; + up = pp->unitptr; temp = refclock_gtlin(rbufp, tbuf, BMAX, &trtmp); /* @@ -452,7 +451,7 @@ arb_poll( * need poll the clock; all others just listen in. */ pp = peer->procptr; - up = (struct arbunit *)pp->unitptr; + up = pp->unitptr; pp->polls++; up->tcswitch = 0; if (write(pp->io.fd, "TQ", 2) != 2) diff --git a/ntpd/refclock_arc.c b/ntpd/refclock_arc.c index 3e35108d6..8ac58f656 100644 --- a/ntpd/refclock_arc.c +++ b/ntpd/refclock_arc.c @@ -591,7 +591,7 @@ arc_event_handler( ) { struct refclockproc *pp = peer->procptr; - register struct arcunit *up = (struct arcunit *)pp->unitptr; + register struct arcunit *up = pp->unitptr; int i; char c; #ifdef DEBUG @@ -691,12 +691,11 @@ arc_start( #endif - up = emalloc(sizeof(*up)); /* Set structure to all zeros... */ - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = arc_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -705,7 +704,7 @@ arc_start( free(up); return(0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -776,7 +775,7 @@ arc_shutdown( peer->action = dummy_event_handler; pp = peer->procptr; - up = (struct arcunit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -876,9 +875,9 @@ arc_receive( /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct arcunit *)pp->unitptr; + up = pp->unitptr; /* @@ -1455,7 +1454,7 @@ request_time( ) { struct refclockproc *pp = peer->procptr; - register struct arcunit *up = (struct arcunit *)pp->unitptr; + register struct arcunit *up = pp->unitptr; #ifdef DEBUG if(debug) { printf("arc: unit %d: requesting time.\n", unit); } #endif @@ -1486,7 +1485,7 @@ arc_poll( int resync_needed; /* Should we start a resync? */ pp = peer->procptr; - up = (struct arcunit *)pp->unitptr; + up = pp->unitptr; #if 0 pp->lencode = 0; memset(pp->a_lastcode, 0, sizeof(pp->a_lastcode)); diff --git a/ntpd/refclock_as2201.c b/ntpd/refclock_as2201.c index af5907391..486c6a39d 100644 --- a/ntpd/refclock_as2201.c +++ b/ntpd/refclock_as2201.c @@ -173,11 +173,10 @@ as2201_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = as2201_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -186,7 +185,7 @@ as2201_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -214,7 +213,7 @@ as2201_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct as2201unit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -239,9 +238,9 @@ as2201_receive( /* * Initialize pointers and read the timecode and timestamp. */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct as2201unit *)pp->unitptr; + up = pp->unitptr; pp->lencode = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &trtmp); #ifdef DEBUG if (debug) diff --git a/ntpd/refclock_atom.c b/ntpd/refclock_atom.c index d8a9d3e27..b3c0d6b46 100644 --- a/ntpd/refclock_atom.c +++ b/ntpd/refclock_atom.c @@ -134,7 +134,7 @@ atom_start( memcpy((char *)&pp->refid, REFID, 4); up = emalloc(sizeof(struct ppsunit)); memset(up, 0, sizeof(struct ppsunit)); - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Open PPS device. This can be any serial or parallel port and @@ -168,7 +168,7 @@ atom_shutdown( struct ppsunit *up; pp = peer->procptr; - up = (struct ppsunit *)pp->unitptr; + up = pp->unitptr; if (up->fddev > 0) close(up->fddev); free(up); @@ -188,7 +188,7 @@ atom_timer( char tbuf[80]; pp = peer->procptr; - up = (struct ppsunit *)pp->unitptr; + up = pp->unitptr; if (refclock_pps(peer, &up->atom, pp->sloppyclockflag) <= 0) return; diff --git a/ntpd/refclock_bancomm.c b/ntpd/refclock_bancomm.c index c1a47a1a8..e72337f92 100644 --- a/ntpd/refclock_bancomm.c +++ b/ntpd/refclock_bancomm.c @@ -266,19 +266,18 @@ vme_start( /* * Allocate unit structure */ - vme = (struct vmeunit *)emalloc(sizeof(struct vmeunit)); - bzero((char *)vme, sizeof(struct vmeunit)); + vme = emalloc_zero(sizeof(struct vmeunit)); /* * Set up the structures */ pp = peer->procptr; - pp->unitptr = (caddr_t) vme; + pp->unitptr = vme; pp->timestarted = current_time; pp->io.clock_recv = vme_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd_vme; /* shouldn't there be an io_addclock() call? */ @@ -310,7 +309,7 @@ vme_shutdown( * Tell the I/O module to turn us off. We're history. */ pp = peer->procptr; - vme = (struct vmeunit *)pp->unitptr; + vme = pp->unitptr; io_closeclock(&pp->io); pp->unitptr = NULL; if (NULL != vme) @@ -350,7 +349,7 @@ vme_poll( struct tm *tadr; pp = peer->procptr; - vme = (struct vmeunit *)pp->unitptr; /* Here is the structure */ + vme = pp->unitptr; /* Here is the structure */ tptr = &vme->vmedata; if ((tptr = get_datumtime(tptr)) == NULL ) { diff --git a/ntpd/refclock_chronolog.c b/ntpd/refclock_chronolog.c index a8b5172c9..ee54b43a6 100644 --- a/ntpd/refclock_chronolog.c +++ b/ntpd/refclock_chronolog.c @@ -116,12 +116,11 @@ chronolog_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->io.clock_recv = chronolog_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -155,7 +154,7 @@ chronolog_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct chronolog_unit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -185,9 +184,9 @@ chronolog_receive( /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct chronolog_unit *)pp->unitptr; + up = pp->unitptr; temp = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &trtmp); if (temp == 0) { @@ -325,7 +324,7 @@ chronolog_poll( char pollchar; pp = peer->procptr; - up = (struct chronolog_unit *)pp->unitptr; + up = pp->unitptr; if (peer->burst == 0 && peer->reach == 0) refclock_report(peer, CEVNT_TIMEOUT); if (up->linect > 0) diff --git a/ntpd/refclock_chu.c b/ntpd/refclock_chu.c index 0a80b672b..88bb35b3e 100644 --- a/ntpd/refclock_chu.c +++ b/ntpd/refclock_chu.c @@ -506,12 +506,11 @@ chu_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->io.clock_recv = chu_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -592,7 +591,7 @@ chu_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; if (up == NULL) return; @@ -618,9 +617,9 @@ chu_receive( struct refclockproc *pp; struct peer *peer; - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * If the audio codec is warmed up, the buffer contains codec @@ -658,9 +657,9 @@ chu_audio_receive( int bufcnt; /* buffer counter */ l_fp ltemp; /* l_fp temp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * Main loop - read until there ain't no more. Note codec @@ -745,7 +744,7 @@ chu_rf( int i, j; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * Bandpass filter. 4th-order elliptic, 500-Hz bandpass centered @@ -970,9 +969,9 @@ chu_serial_receive( u_char *dpt; /* receive buffer pointer */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; dpt = (u_char *)&rbufp->recv_space; chu_decode(peer, *dpt, rbufp->recv_time); @@ -996,7 +995,7 @@ chu_decode( double dtemp; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * If the interval since the last character is greater than the @@ -1044,7 +1043,7 @@ chu_burst( int i; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * Correlate a block of five characters with the next block of @@ -1107,7 +1106,7 @@ chu_b( int i; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * In a format B burst, a character is considered valid only if @@ -1183,7 +1182,7 @@ chu_a( int i, j, k; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * Determine correct burst phase. There are three cases @@ -1334,7 +1333,7 @@ chu_second( double dtemp; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * This routine is called once per minute to process the @@ -1441,7 +1440,7 @@ chu_major( int i, j, k; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * Majority decoder. Each burst encodes two replications at each @@ -1502,7 +1501,7 @@ chu_clear( int i, j; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * Clear stuff for the minute. @@ -1535,7 +1534,7 @@ chu_newchan( int i; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * The radio can be tuned to three channels: 0 (3330 kHz), 1 @@ -1653,7 +1652,7 @@ chu_gain( struct chuunit *up; pp = peer->procptr; - up = (struct chuunit *)pp->unitptr; + up = pp->unitptr; /* * Apparently, the codec uses only the high order bits of the diff --git a/ntpd/refclock_datum.c b/ntpd/refclock_datum.c index 68804bf69..d2de8fde4 100644 --- a/ntpd/refclock_datum.c +++ b/ntpd/refclock_datum.c @@ -129,7 +129,6 @@ struct datum_pts_unit { struct peer *peer; /* peer used by ntp */ - struct refclockio io; /* io structure used by ntp */ int PTS_fd; /* file descriptor for PTS */ u_int unit; /* id for unit */ u_long timestarted; /* time started */ @@ -156,8 +155,6 @@ struct datum_pts_unit { static char TIME_REQUEST[6]; /* request message sent to datum for time */ static int nunits; /* number of active units */ -static struct datum_pts_unit -**datum_pts_unit; /* dynamic array of datum PTS structures */ /* ** Callback function prototypes that ntpd needs to know about. @@ -222,7 +219,7 @@ datum_pts_start( struct peer *peer ) { - struct datum_pts_unit **temp_datum_pts_unit; + struct refclockproc *pp; struct datum_pts_unit *datum_pts; int fd; #ifdef HAVE_TERMIOS @@ -247,17 +244,7 @@ datum_pts_start( /* ** Create the memory for the new unit */ - - temp_datum_pts_unit = (struct datum_pts_unit **) - emalloc((nunits+1)*sizeof(struct datum_pts_unit *)); - if (nunits > 0) memcpy(temp_datum_pts_unit, datum_pts_unit, - nunits*sizeof(struct datum_pts_unit *)); - free(datum_pts_unit); - datum_pts_unit = temp_datum_pts_unit; - datum_pts_unit[nunits] = (struct datum_pts_unit *) - emalloc(sizeof(struct datum_pts_unit)); - datum_pts = datum_pts_unit[nunits]; - + datum_pts = emalloc_zero(sizeof(*datum_pts)); datum_pts->unit = unit; /* set my unit id */ datum_pts->yearstart = 0; /* initialize the yearstart to 0 */ datum_pts->sigma2 = 0.0; /* initialize the sigma2 to 0 */ @@ -280,8 +267,6 @@ datum_pts_start( ** ntp folks so that it can become part of their regular distribution. */ -#ifdef HAVE_TERMIOS - memset(&arg, 0, sizeof(arg)); arg.c_iflag = IGNBRK; @@ -293,41 +278,31 @@ datum_pts_start( tcsetattr(datum_pts->PTS_fd, TCSANOW, &arg); -#else - - msyslog(LOG_ERR, "Datum_PTS: Termios not supported in this driver"); - (void)close(datum_pts->PTS_fd); - - peer->precision = PRECISION; - pp->clockdesc = DESCRIPTION; - memcpy((char *)&pp->refid, REFID, 4); - - return 0; - -#endif - /* ** Initialize the ntpd IO structure */ datum_pts->peer = peer; - datum_pts->io.clock_recv = datum_pts_receive; - datum_pts->io.srcclock = (caddr_t)datum_pts; - datum_pts->io.datalen = 0; - datum_pts->io.fd = datum_pts->PTS_fd; - - if (!io_addclock(&(datum_pts->io))) { - + pp = peer->procptr; + pp->io.clock_recv = datum_pts_receive; + pp->io.srcclock = peer; + pp->io.datalen = 0; + pp->io.fd = datum_pts->PTS_fd; + + if (!io_addclock(&pp->io)) { + pp->io.fd = -1; #ifdef DEBUG_DATUM_PTC if (debug) printf("Problem adding clock\n"); #endif msyslog(LOG_ERR, "Datum_PTS: Problem adding clock"); - (void)close(datum_pts->PTS_fd); + close(datum_pts->PTS_fd); + free(datum_pts); return 0; } + peer->procptr->unitptr = datum_pts; /* ** Now add one to the number of units and return a successful code @@ -350,8 +325,8 @@ datum_pts_shutdown( struct peer *peer ) { - int i,j; - struct datum_pts_unit **temp_datum_pts_unit; + struct refclockproc *pp; + struct datum_pts_unit *datum_pts; #ifdef DEBUG_DATUM_PTC if (debug) @@ -361,64 +336,18 @@ datum_pts_shutdown( msyslog(LOG_ERR, "Datum_PTS: Shutdown Datum PTS"); /* - ** First we have to find the right unit (i.e., the one with the same id). - ** We do this by looping through the dynamic array of units intil we find - ** it. Note, that I don't simply use an array with a maximimum number of - ** Datum PTS units. Everything is completely dynamic. + ** We found the unit so close the file descriptor and free up the memory used + ** by the structure. */ - - for (i=0; iunit == unit) { - - /* - ** We found the unit so close the file descriptor and free up the memory used - ** by the structure. - */ - - io_closeclock(&datum_pts_unit[i]->io); - close(datum_pts_unit[i]->PTS_fd); - free(datum_pts_unit[i]); - - /* - ** Now clean up the datum_pts_unit dynamic array so that there are no holes. - ** This may mean moving pointers around, etc., to keep things compact. - */ - - if (nunits > 1) { - - temp_datum_pts_unit = (struct datum_pts_unit **) - emalloc((nunits-1)*sizeof(struct datum_pts_unit *)); - if (i!= 0) memcpy(temp_datum_pts_unit, datum_pts_unit, - i*sizeof(struct datum_pts_unit *)); - - for (j=i+1; jprocptr; + datum_pts = pp->unitptr; + if (NULL != datum_pts) { + io_closeclock(&pp->io); + free(datum_pts); } - -#ifdef DEBUG_DATUM_PTC - if (debug) - printf("Error, could not shut down unit %d\n",unit); -#endif - - msyslog(LOG_ERR, "Datum_PTS: Could not shut down Datum PTS unit %d",unit); - } + /*......................................................................*/ /* datum_pts_poll - this routine sends out the time request to the */ /* Datum PTS device. The time will be passed back in the */ @@ -431,11 +360,11 @@ datum_pts_poll( struct peer *peer ) { - int i; - int unit_index; int error_code; struct datum_pts_unit *datum_pts; + datum_pts = peer->procptr->unitptr; + #ifdef DEBUG_DATUM_PTC if (debug) printf("Poll Datum PTS\n"); @@ -444,35 +373,10 @@ datum_pts_poll( /* ** Find the right unit and send out a time request once it is found. */ - - unit_index = -1; - for (i=0; iunit == unit) { - unit_index = i; - datum_pts = datum_pts_unit[i]; - error_code = write(datum_pts->PTS_fd, TIME_REQUEST, 6); - if (error_code != 6) perror("TIME_REQUEST"); - datum_pts->nbytes = 0; - break; - } - } - - /* - ** Print out an error message if we could not find the right unit. - */ - - if (unit_index == -1) { - -#ifdef DEBUG_DATUM_PTC - if (debug) - printf("Error, could not poll unit %d\n",unit); -#endif - - msyslog(LOG_ERR, "Datum_PTS: Could not poll unit %d",unit); - return; - - } - + error_code = write(datum_pts->PTS_fd, TIME_REQUEST, 6); + if (error_code != 6) + perror("TIME_REQUEST"); + datum_pts->nbytes = 0; } @@ -534,7 +438,6 @@ datum_pts_init(void) ** NULL since there are no units defined yet. */ - datum_pts_unit = NULL; nunits = 0; } @@ -576,6 +479,7 @@ datum_pts_receive( { int i; l_fp tstmp; + struct peer *p; struct datum_pts_unit *datum_pts; char *dpt; int dpend; @@ -592,13 +496,14 @@ datum_pts_receive( ** Get the time code (maybe partial) message out of the rbufp buffer. */ - datum_pts = (struct datum_pts_unit *)rbufp->recv_srcclock; + p = rbufp->recv_peer; + datum_pts = p->procptr->unitptr; dpt = (char *)&rbufp->recv_space; dpend = rbufp->recv_length; #ifdef DEBUG_DATUM_PTC if (debug) - printf("Receive Datum PTS: %d bytes\n", dpend); + printf("Receive Datum PTS: %d bytes\n", dpend); #endif /* */ diff --git a/ntpd/refclock_dumbclock.c b/ntpd/refclock_dumbclock.c index 4876a6685..89f0f4748 100644 --- a/ntpd/refclock_dumbclock.c +++ b/ntpd/refclock_dumbclock.c @@ -127,12 +127,11 @@ dumbclock_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->io.clock_recv = dumbclock_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -178,7 +177,7 @@ dumbclock_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct dumbclock_unit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -208,9 +207,9 @@ dumbclock_receive( /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct dumbclock_unit *)pp->unitptr; + up = pp->unitptr; temp = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &trtmp); if (temp == 0) { @@ -364,7 +363,7 @@ dumbclock_poll( */ #if 0 pp = peer->procptr; - up = (struct dumbclock_unit *)pp->unitptr; + up = pp->unitptr; if (peer->reach == 0) refclock_report(peer, CEVNT_TIMEOUT); if (up->linect > 0) diff --git a/ntpd/refclock_fg.c b/ntpd/refclock_fg.c index fa2a91706..bcea1a17a 100644 --- a/ntpd/refclock_fg.c +++ b/ntpd/refclock_fg.c @@ -119,9 +119,9 @@ fg_start( up = emalloc(sizeof(struct fgunit)); memset(up, 0, sizeof(struct fgunit)); pp = peer->procptr; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->io.clock_recv = fg_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -163,7 +163,7 @@ fg_shutdown( struct fgunit *up; pp = peer->procptr; - up = (struct fgunit *)pp->unitptr; + up = pp->unitptr; if (pp->io.fd != -1) io_closeclock(&pp->io); if (up != NULL) @@ -230,9 +230,9 @@ fg_receive( * Initialize pointers and read the timecode and timestamp * We can't use gtlin function because we need bynary data in buf */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct fgunit *)pp->unitptr; + up = pp->unitptr; /* * Below hug to implement receiving of status information diff --git a/ntpd/refclock_gpsvme.c b/ntpd/refclock_gpsvme.c index c3322fdeb..8d9f1f6d9 100644 --- a/ntpd/refclock_gpsvme.c +++ b/ntpd/refclock_gpsvme.c @@ -122,10 +122,10 @@ psc_start( /* initialize peer variables */ pp = peer->procptr; pp->io.clock_recv = noentry; - pp->io.srcclock = (caddr_t) peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = -1; - pp->unitptr = (caddr_t) up; + pp->unitptr = up; get_systime(&pp->lastrec); memcpy(&pp->refid, REFID, 4); peer->precision = PRECISION; diff --git a/ntpd/refclock_heath.c b/ntpd/refclock_heath.c index 1e6cb893c..797b27c83 100644 --- a/ntpd/refclock_heath.c +++ b/ntpd/refclock_heath.c @@ -228,7 +228,7 @@ heath_start( return (0); pp = peer->procptr; pp->io.clock_recv = heath_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -283,7 +283,7 @@ heath_receive( /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; pp->lencode = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &trtmp); diff --git a/ntpd/refclock_hopfpci.c b/ntpd/refclock_hopfpci.c index 284e3011c..11fc9a0bf 100644 --- a/ntpd/refclock_hopfpci.c +++ b/ntpd/refclock_hopfpci.c @@ -124,8 +124,7 @@ hopfpci_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); #ifndef SYS_WINNT @@ -141,10 +140,10 @@ hopfpci_start( pp = peer->procptr; pp->io.clock_recv = noentry; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = INVALID_SOCKET; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; get_systime(&pp->lastrec); diff --git a/ntpd/refclock_hopfser.c b/ntpd/refclock_hopfser.c index 48eea0022..699f0e86f 100644 --- a/ntpd/refclock_hopfser.c +++ b/ntpd/refclock_hopfser.c @@ -146,12 +146,11 @@ hopfserial_start ( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->io.clock_recv = hopfserial_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -193,7 +192,7 @@ hopfserial_shutdown ( struct refclockproc *pp; pp = peer->procptr; - up = (struct hopfclock_unit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); @@ -224,9 +223,9 @@ hopfserial_receive ( /* * Initialize pointers and read the timecode and timestamp. */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct hopfclock_unit *)pp->unitptr; + up = pp->unitptr; if (up->rpt_next == 0 ) return; @@ -356,7 +355,7 @@ hopfserial_poll ( struct refclockproc *pp; pp = peer->procptr; - up = (struct hopfclock_unit *)pp->unitptr; + up = pp->unitptr; pp->polls++; up->rpt_next = 1; diff --git a/ntpd/refclock_hpgps.c b/ntpd/refclock_hpgps.c index 66e2a385d..4be8a7164 100644 --- a/ntpd/refclock_hpgps.c +++ b/ntpd/refclock_hpgps.c @@ -174,11 +174,10 @@ hpgps_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = hpgps_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -187,7 +186,7 @@ hpgps_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -227,7 +226,7 @@ hpgps_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct hpgpsunit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -264,9 +263,9 @@ hpgps_receive( /* * Initialize pointers and read the receiver response */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct hpgpsunit *)pp->unitptr; + up = pp->unitptr; *pp->a_lastcode = '\0'; pp->lencode = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &trtmp); @@ -607,7 +606,7 @@ hpgps_poll( * declare a timeout and keep going. */ pp = peer->procptr; - up = (struct hpgpsunit *)pp->unitptr; + up = pp->unitptr; if (up->pollcnt == 0) refclock_report(peer, CEVNT_TIMEOUT); else diff --git a/ntpd/refclock_irig.c b/ntpd/refclock_irig.c index 4a6f393e1..ad52aa242 100644 --- a/ntpd/refclock_irig.c +++ b/ntpd/refclock_irig.c @@ -332,11 +332,10 @@ irig_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = irig_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -345,7 +344,7 @@ irig_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -389,7 +388,7 @@ irig_shutdown( struct irigunit *up; pp = peer->procptr; - up = (struct irigunit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -420,9 +419,9 @@ irig_receive( int bufcnt; /* buffer counter */ l_fp ltemp; /* l_fp temp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct irigunit *)pp->unitptr; + up = pp->unitptr; /* * Main loop - read until there ain't no more. Note codec @@ -518,7 +517,7 @@ irig_rf( double irig_b, irig_e; /* irig filter outputs */ pp = peer->procptr; - up = (struct irigunit *)pp->unitptr; + up = pp->unitptr; /* * IRIG-B filter. Matlab 4th-order IIR elliptic, 800-1200 Hz @@ -600,7 +599,7 @@ irig_base( int carphase; /* carrier phase */ pp = peer->procptr; - up = (struct irigunit *)pp->unitptr; + up = pp->unitptr; /* * Synchronous baud integrator. Corresponding samples of current @@ -753,7 +752,7 @@ irig_baud( l_fp ltemp; pp = peer->procptr; - up = (struct irigunit *)pp->unitptr; + up = pp->unitptr; /* * The PLL time constant starts out small, in order to @@ -847,8 +846,9 @@ irig_decode( char spare[2 + 1]; /* mulligan digits */ int temp; + syncdig = 0; pp = peer->procptr; - up = (struct irigunit *)pp->unitptr; + up = pp->unitptr; /* * Assemble frame bits. @@ -983,7 +983,7 @@ irig_poll( struct irigunit *up; pp = peer->procptr; - up = (struct irigunit *)pp->unitptr; + up = pp->unitptr; if (pp->coderecv == pp->codeproc) { refclock_report(peer, CEVNT_TIMEOUT); @@ -1020,7 +1020,7 @@ irig_gain( struct irigunit *up; pp = peer->procptr; - up = (struct irigunit *)pp->unitptr; + up = pp->unitptr; /* * Apparently, the codec uses only the high order bits of the diff --git a/ntpd/refclock_jjy.c b/ntpd/refclock_jjy.c index 267bc4fa0..d648587df 100644 --- a/ntpd/refclock_jjy.c +++ b/ntpd/refclock_jjy.c @@ -409,9 +409,9 @@ jjy_start ( int unit, struct peer *peer ) } pp = peer->procptr ; - pp->unitptr = (caddr_t) up ; + pp->unitptr = up ; pp->io.clock_recv = jjy_receive ; - pp->io.srcclock = (caddr_t) peer ; + pp->io.srcclock = peer ; pp->io.datalen = 0 ; pp->io.fd = fd ; if ( ! io_addclock(&pp->io) ) { @@ -446,7 +446,7 @@ jjy_shutdown ( int unit, struct peer *peer ) struct refclockproc *pp; pp = peer->procptr ; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; if ( -1 != pp->io.fd ) io_closeclock ( &pp->io ) ; if ( NULL != up ) @@ -474,9 +474,9 @@ jjy_receive ( struct recvbuf *rbufp ) /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *) rbufp->recv_srcclock ; + peer = rbufp->recv_peer ; pp = peer->procptr ; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; /* * Get next input line @@ -672,9 +672,9 @@ jjy_receive_tristate_jjy01 ( struct recvbuf *rbufp ) /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *) rbufp->recv_srcclock ; + peer = rbufp->recv_peer ; pp = peer->procptr ; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; if ( up->linediscipline == LDISC_RAW ) { pBuf = up->rawbuf ; @@ -854,9 +854,9 @@ jjy_receive_cdex_jst2000 ( struct recvbuf *rbufp ) /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *) rbufp->recv_srcclock ; + peer = rbufp->recv_peer ; pp = peer->procptr ; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; if ( up->linediscipline == LDISC_RAW ) { pBuf = up->rawbuf ; @@ -934,9 +934,9 @@ jjy_receive_echokeisokuki_lt2000 ( struct recvbuf *rbufp ) /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *) rbufp->recv_srcclock ; + peer = rbufp->recv_peer ; pp = peer->procptr ; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; if ( up->linediscipline == LDISC_RAW ) { pBuf = up->rawbuf ; @@ -1093,9 +1093,9 @@ jjy_receive_citizentic_jjy200 ( struct recvbuf *rbufp ) /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *) rbufp->recv_srcclock ; + peer = rbufp->recv_peer ; pp = peer->procptr ; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; if ( up->linediscipline == LDISC_RAW ) { pBuf = up->rawbuf ; @@ -1177,7 +1177,7 @@ jjy_poll ( int unit, struct peer *peer ) struct refclockproc *pp; pp = peer->procptr; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; if ( pp->polls > 0 && up->linecount == 0 ) { /* @@ -1239,7 +1239,7 @@ jjy_poll_tristate_jjy01 ( int unit, struct peer *peer ) int iCmdLen ; pp = peer->procptr; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; if ( ( pp->sloppyclockflag & CLK_FLAG1 ) == 0 ) { up->linecount = 2 ; @@ -1311,7 +1311,7 @@ jjy_poll_echokeisokuki_lt2000 ( int unit, struct peer *peer ) char sCmd[2] ; pp = peer->procptr; - up = (struct jjyunit *) pp->unitptr ; + up = pp->unitptr ; /* * Send "T" or "C" command diff --git a/ntpd/refclock_jupiter.c b/ntpd/refclock_jupiter.c index da5a3dbeb..ee3a7629b 100644 --- a/ntpd/refclock_jupiter.c +++ b/ntpd/refclock_jupiter.c @@ -60,11 +60,6 @@ #define putshort(s) ((u_short)(s)) #endif -/* XXX */ -#ifdef sun -char *strerror(int); -#endif - /* * This driver supports the Rockwell Jupiter GPS Receiver board * adapted to precision timing applications. It requires the @@ -138,8 +133,9 @@ struct instance { static void jupiter_canmsg (struct instance *, u_int); static u_short jupiter_cksum (u_short *, u_int); static int jupiter_config (struct instance *); -static void jupiter_debug (struct peer *, char *, char *, ...) - __attribute__ ((format (printf, 3, 4))); +static void jupiter_debug (struct peer *, const char *, + const char *, ...) + __attribute__ ((format (printf, 3, 4))); static char * jupiter_parse_t (struct instance *, u_short *); static char * jupiter_parse_gpos (struct instance *, u_short *); static void jupiter_platform (struct instance *, u_int); @@ -191,26 +187,26 @@ jupiter_start( snprintf(gpsdev, sizeof(gpsdev), DEVICE, unit); fd = refclock_open(gpsdev, SPEED232, LDISC_RAW); if (fd <= 0) { - jupiter_debug(peer, "jupiter_start", "open %s: %s", - gpsdev, strerror(errno)); + jupiter_debug(peer, "jupiter_start", "open %s: %m", + gpsdev); return (0); } /* Allocate unit structure */ - instance = emalloc(sizeof(*instance)); - memset(instance, 0, sizeof(*instance)); + instance = emalloc_zero(sizeof(*instance)); instance->peer = peer; pp = peer->procptr; pp->io.clock_recv = jupiter_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { close(fd); + pp->io.fd = -1; free(instance); return (0); } - pp->unitptr = (caddr_t)instance; + pp->unitptr = instance; /* * Initialize miscellaneous variables @@ -257,7 +253,7 @@ jupiter_shutdown(int unit, struct peer *peer) struct refclockproc *pp; pp = peer->procptr; - instance = (struct instance *)pp->unitptr; + instance = pp->unitptr; if (!instance) return; @@ -268,7 +264,8 @@ jupiter_shutdown(int unit, struct peer *peer) } #endif /* HAVE_PPSAPI */ - io_closeclock(&pp->io); + if (pp->io.fd != -1) + io_closeclock(&pp->io); free(instance); } @@ -440,7 +437,7 @@ jupiter_poll(int unit, struct peer *peer) struct refclockproc *pp; pp = peer->procptr; - instance = (struct instance *)pp->unitptr; + instance = pp->unitptr; /* * You don't need to poll this clock. It puts out timecodes @@ -485,7 +482,7 @@ jupiter_control( u_char sloppyclockflag; pp = peer->procptr; - instance = (struct instance *)pp->unitptr; + instance = pp->unitptr; DTOLFP(pp->fudgetime2, &instance->limit); /* Force positive value. */ @@ -530,9 +527,9 @@ jupiter_receive(struct recvbuf *rbufp) l_fp tstamp; /* Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - instance = (struct instance *)pp->unitptr; + instance = pp->unitptr; bp = (u_char *)rbufp->recv_buffer; bpcnt = rbufp->recv_length; @@ -873,36 +870,27 @@ jupiter_parse_gpos(struct instance *instance, u_short *sp) /* * jupiter_debug - print debug messages */ -#if defined(__STDC__) || defined(SYS_WINNT) -static void -jupiter_debug(struct peer *peer, char *function, char *fmt, ...) -#else static void -jupiter_debug(peer, function, fmt, va_alist) - struct peer *peer; - char *function; - char *fmt; -#endif /* __STDC__ */ +jupiter_debug( + struct peer * peer, + const char * function, + const char * fmt, + ... + ) { - char buffer[200]; - va_list ap; + char buffer[200]; + va_list ap; -#if defined(__STDC__) || defined(SYS_WINNT) va_start(ap, fmt); -#else - va_start(ap); -#endif /* __STDC__ */ /* * Print debug message to stdout * In the future, we may want to get get more creative... */ - vsnprintf(buffer, sizeof(buffer), fmt, ap); - record_clock_stats(&(peer->srcadr), buffer); + mvsnprintf(buffer, sizeof(buffer), fmt, ap); + record_clock_stats(&peer->srcadr, buffer); #ifdef DEBUG if (debug) { - fprintf(stdout, "%s: ", function); - fprintf(stdout, buffer); - fprintf(stdout, "\n"); + printf("%s: %s\n", function, buffer); fflush(stdout); } #endif @@ -930,7 +918,7 @@ jupiter_send(struct instance *instance, struct jheader *hp) } if ((cc = write(instance->peer->procptr->io.fd, (char *)hp, size)) < 0) { - snprintf(errstr, sizeof(errstr), "write: %s", strerror(errno)); + msnprintf(errstr, sizeof(errstr), "write: %m"); return (errstr); } else if (cc != (int)size) { snprintf(errstr, sizeof(errstr), "short write (%d != %u)", cc, size); diff --git a/ntpd/refclock_leitch.c b/ntpd/refclock_leitch.c index 144690629..7a00dd6d1 100644 --- a/ntpd/refclock_leitch.c +++ b/ntpd/refclock_leitch.c @@ -391,7 +391,7 @@ leitch_start( leitch->fudge1 = 15; /* 15ms */ leitch->leitchio.clock_recv = leitch_receive; - leitch->leitchio.srcclock = (caddr_t) leitch; + leitch->leitchio.srcclock = peer; leitch->leitchio.datalen = 0; leitch->leitchio.fd = fd232; if (!io_addclock(&leitch->leitchio)) { @@ -426,7 +426,7 @@ leitch_receive( struct recvbuf *rbufp ) { - struct leitchunit *leitch = (struct leitchunit *)rbufp->recv_srcclock; + struct leitchunit *leitch = rbufp->recv_peer->procptr->unitptr; #ifdef DEBUG if (debug) diff --git a/ntpd/refclock_msfees.c b/ntpd/refclock_msfees.c index 612b890f0..5571e9ab6 100644 --- a/ntpd/refclock_msfees.c +++ b/ntpd/refclock_msfees.c @@ -533,7 +533,7 @@ msfees_start( ees->timestarted= current_time; ees->ttytype = 0; ees->io.clock_recv= ees_receive; - ees->io.srcclock= (caddr_t)ees; + ees->io.srcclock= ees; ees->io.datalen = 0; ees->io.fd = fd232; @@ -585,7 +585,7 @@ msfees_start( peer->refid = htonl(EESHSREFID); } unitinuse[unit] = 1; - pp->unitptr = (caddr_t) &eesunits[unit]; + pp->unitptr = &eesunits[unit]; pp->clockdesc = EESDESCRIPTION; msyslog(LOG_ERR, "ees clock: %s OK on %d", eesdev, unit); return (1); diff --git a/ntpd/refclock_mx4200.c b/ntpd/refclock_mx4200.c index dd74cc056..44b3e2463 100644 --- a/ntpd/refclock_mx4200.c +++ b/ntpd/refclock_mx4200.c @@ -226,11 +226,10 @@ mx4200_start( /* * Allocate unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = mx4200_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -239,7 +238,7 @@ mx4200_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -266,7 +265,7 @@ mx4200_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -289,7 +288,7 @@ mx4200_config( int mode; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; /* * Initialize the unit variables @@ -489,7 +488,7 @@ mx4200_ref( char nsc, ewc; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; /* Should never happen! */ if (up->moving) return; @@ -607,7 +606,7 @@ mx4200_poll( struct refclockproc *pp; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; /* * You don't need to poll this clock. It puts out timecodes @@ -674,9 +673,9 @@ mx4200_receive( /* * Initialize pointers and read the timecode and timestamp. */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; /* * If operating mode has been changed, then reinitialize the receiver @@ -960,7 +959,7 @@ mx4200_parse_t( int oscillator_offset, time_mark_error, time_bias; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; leapsec_warn = 0; /* Not all receivers output leap second warnings (!) */ sscanf(pp->a_lastcode, @@ -1240,7 +1239,7 @@ mx4200_parse_p( char north_south, east_west; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; /* Should never happen! */ if (up->moving) return ("mobile platform - no pos!"); @@ -1459,7 +1458,7 @@ mx4200_parse_s( int sentence_type; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; sscanf ( pp->a_lastcode, "$PMVXG,%d", &sentence_type); @@ -1504,7 +1503,7 @@ mx4200_pps( struct timespec timeout; pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; /* * Grab the timestamp of the PPS signal. @@ -1515,8 +1514,8 @@ mx4200_pps( if (time_pps_fetch(up->pps_h, PPS_TSFMT_TSPEC, &(up->pps_i), &timeout) < 0) { mx4200_debug(peer, - "mx4200_pps: time_pps_fetch: serial=%lu, %s\n", - (unsigned long)up->pps_i.assert_sequence, strerror(errno)); + "mx4200_pps: time_pps_fetch: serial=%lu, %m\n", + (unsigned long)up->pps_i.assert_sequence); refclock_report(peer, CEVNT_FAULT); return(1); } @@ -1557,15 +1556,8 @@ mx4200_pps( /* * mx4200_debug - print debug messages */ -#if defined(__STDC__) static void mx4200_debug(struct peer *peer, char *fmt, ...) -#else -static void -mx4200_debug(peer, fmt, va_alist) - struct peer *peer; - char *fmt; -#endif /* __STDC__ */ { #ifdef DEBUG va_list ap; @@ -1573,22 +1565,16 @@ mx4200_debug(peer, fmt, va_alist) struct mx4200unit *up; if (debug) { - -#if defined(__STDC__) va_start(ap, fmt); -#else - va_start(ap); -#endif /* __STDC__ */ pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; - + up = pp->unitptr; /* * Print debug message to stdout * In the future, we may want to get get more creative... */ - vprintf(fmt, ap); + mvprintf(fmt, ap); va_end(ap); } @@ -1625,7 +1611,7 @@ mx4200_send(peer, fmt, va_alist) #endif /* __STDC__ */ pp = peer->procptr; - up = (struct mx4200unit *)pp->unitptr; + up = pp->unitptr; cp = buf; *cp++ = '$'; diff --git a/ntpd/refclock_neoclock4x.c b/ntpd/refclock_neoclock4x.c index 059ee4221..4660ea27a 100644 --- a/ntpd/refclock_neoclock4x.c +++ b/ntpd/refclock_neoclock4x.c @@ -294,9 +294,9 @@ neoclock4x_start(int unit, memset((char *)up, 0, sizeof(struct neoclock4x_unit)); pp = peer->procptr; pp->clockdesc = "NeoClock4X"; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->io.clock_recv = neoclock4x_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; /* @@ -401,7 +401,7 @@ neoclock4x_shutdown(int unit, pp = peer->procptr; if(pp != NULL) { - up = (struct neoclock4x_unit *)pp->unitptr; + up = pp->unitptr; if(up != NULL) { if(-1 != pp->io.fd) @@ -455,9 +455,9 @@ neoclock4x_receive(struct recvbuf *rbufp) unsigned char calc_chksum; int recv_chksum; - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct neoclock4x_unit *)pp->unitptr; + up = pp->unitptr; /* wait till poll interval is reached */ if(0 == up->recvnow) @@ -664,7 +664,7 @@ neoclock4x_poll(int unit, struct refclockproc *pp; pp = peer->procptr; - up = (struct neoclock4x_unit *)pp->unitptr; + up = pp->unitptr; pp->polls++; up->recvnow = 1; @@ -692,7 +692,7 @@ neoclock4x_control(int unit, return; } - up = (struct neoclock4x_unit *)pp->unitptr; + up = pp->unitptr; if(NULL == up) { msyslog(LOG_ERR, "NeoClock4X(%d): control: unit invalid/inactive", unit); @@ -945,7 +945,7 @@ neol_query_firmware(int fd, { if(EAGAIN != errno) { - msyslog(LOG_DEBUG, "NeoClock4x(%d): read: %s", unit ,strerror(errno)); + msyslog(LOG_DEBUG, "NeoClock4x(%d): read: %m", unit); read_errors++; } else diff --git a/ntpd/refclock_nmea.c b/ntpd/refclock_nmea.c index 744ac1ee4..3ac7d1e14 100644 --- a/ntpd/refclock_nmea.c +++ b/ntpd/refclock_nmea.c @@ -304,6 +304,7 @@ nmea_start( char *baudtext; pp = peer->procptr; + pp->io.fd = -1; /* Open serial port. Use CLK line discipline, if available. Use * baudrate based on the value of bit 4/5/6 @@ -343,6 +344,7 @@ nmea_start( #endif } + pp->io.fd = -1; fd = refclock_open(device, baudrate, LDISC_CLK); if (fd <= 0) { #ifdef HAVE_READLINK @@ -361,10 +363,10 @@ nmea_start( char *nmea_host, *nmea_tail; u_long nmea_port; int len; - struct hostent *he; - struct protoent *p; - struct sockaddr_in so_addr; - + struct addrinfo hints; + struct addrinfo *ai; + int rc; + if ((len = readlink(device,buffer,sizeof(buffer))) == -1) return(0); buffer[len] = 0; @@ -377,24 +379,34 @@ nmea_start( nmea_port > USHRT_MAX) return 0; - if ((he = gethostbyname(nmea_host)) == NULL) - return(0); - if ((p = getprotobyname("tcp")) == NULL) - return(0); - memset(&so_addr, 0, sizeof(so_addr)); - so_addr.sin_family = AF_INET; - so_addr.sin_port = htons((u_short)nmea_port); - so_addr.sin_addr = *((struct in_addr *) he->h_addr); + /* + * This getaddrinfo() is naughty in ntpd's nonblocking + * main thread, but you have to go out of your wary to + * use this code and typically the blocking is at + * startup where its impact is reduced. + */ + ZERO(hints); + hints.ai_flags = Z_AI_NUMERICSERV; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + rc = getaddrinfo(nmea_host, nmea_tail, &hints, &ai); + if (rc != 0) + return 0; - if ((fd = socket(PF_INET,SOCK_STREAM,p->p_proto)) == -1) - return(0); - if (connect(fd,(struct sockaddr *)&so_addr, sizeof(so_addr)) == -1) { + fd = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); + if (INVALID_SOCKET == fd) { + freeaddrinfo(ai); + return 0; + } + rc = connect(fd, ai->ai_addr, ai->ai_addrlen); + freeaddrinfo(ai); + if (-1 == rc) { close(fd); - return (0); + return 0; } #else - pp->io.fd = -1; - return (0); + return 0; #endif } @@ -404,16 +416,16 @@ nmea_start( /* Allocate and initialize unit structure */ up = emalloc_zero(sizeof(*up)); pp->io.clock_recv = nmea_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { - pp->io.fd = -1; close(fd); + pp->io.fd = -1; free(up); - return (0); + return 0; } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* force change detection on first valid message */ up->last_daytime = -1; /* force checksum on GPRMC, see below */ @@ -431,7 +443,7 @@ nmea_start( */ gps_send(fd, "PMOTG,RMC,0001", peer); - return (1); + return 1; } @@ -455,7 +467,7 @@ nmea_shutdown( UNUSED_ARG(unit); pp = peer->procptr; - up = (struct nmeaunit *)pp->unitptr; + up = pp->unitptr; if (up != NULL) { #ifdef HAVE_PPSAPI if (up->ppsapi_lit) { @@ -493,7 +505,7 @@ nmea_control( UNUSED_ARG(out_st); pp = peer->procptr; - up = (struct nmeaunit *)pp->unitptr; + up = pp->unitptr; if (!(CLK_FLAG1 & pp->sloppyclockflag)) { if (!up->ppsapi_tried) @@ -563,7 +575,7 @@ nmea_timer( UNUSED_ARG(unit); pp = peer->procptr; - up = (struct nmeaunit *)pp->unitptr; + up = pp->unitptr; if (up->ppsapi_lit && up->ppsapi_gate && refclock_pps(peer, &up->atom, pp->sloppyclockflag) > 0) { @@ -712,7 +724,7 @@ nmea_receive( /* declare & init control structure ptrs */ struct peer * const peer = rbufp->recv_peer; struct refclockproc * const pp = peer->procptr; - struct nmeaunit * const up = (struct nmeaunit*)pp->unitptr; + struct nmeaunit * const up = pp->unitptr; /* Use these variables to hold data until we decide its worth keeping */ struct nmeadata rdata; @@ -1002,7 +1014,7 @@ nmea_poll( struct refclockproc *pp; pp = peer->procptr; - up = (struct nmeaunit *)pp->unitptr; + up = pp->unitptr; # if 0 /* diff --git a/ntpd/refclock_oncore.c b/ntpd/refclock_oncore.c index 6f31a5db2..13a8af595 100644 --- a/ntpd/refclock_oncore.c +++ b/ntpd/refclock_oncore.c @@ -730,7 +730,7 @@ oncore_start( return(0); pp->io.clock_recv = oncore_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd1; if (!io_addclock(&pp->io)) { @@ -740,7 +740,7 @@ oncore_start( free(instance); return (0); } - pp->unitptr = (caddr_t)instance; + pp->unitptr = instance; #ifdef ONCORE_SHMEM_STATUS /* @@ -783,7 +783,7 @@ oncore_shutdown( struct refclockproc *pp; pp = peer->procptr; - instance = (struct instance *) pp->unitptr; + instance = pp->unitptr; if (pp->io.fd != -1) io_closeclock(&pp->io); @@ -817,7 +817,7 @@ oncore_poll( { struct instance *instance; - instance = (struct instance *) peer->procptr->unitptr; + instance = peer->procptr->unitptr; if (instance->timeout) { instance->timeout--; if (instance->timeout == 0) { @@ -1433,8 +1433,8 @@ oncore_receive( struct peer *peer; struct instance *instance; - peer = (struct peer *)rbufp->recv_srcclock; - instance = (struct instance *) peer->procptr->unitptr; + peer = rbufp->recv_peer; + instance = peer->procptr->unitptr; p = (u_char *) &rbufp->recv_space; #ifdef ONCORE_VERBOSE_RECEIVE diff --git a/ntpd/refclock_palisade.c b/ntpd/refclock_palisade.c index b27c2721d..dfa45034b 100644 --- a/ntpd/refclock_palisade.c +++ b/ntpd/refclock_palisade.c @@ -305,8 +305,7 @@ palisade_start ( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); up->type = CLK_TYPE(peer); switch (up->type) { @@ -342,7 +341,7 @@ palisade_start ( pp = peer->procptr; pp->io.clock_recv = palisade_io; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -358,7 +357,7 @@ palisade_start ( /* * Initialize miscellaneous variables */ - pp->unitptr = (caddr_t)up; + pp->unitptr = up; pp->clockdesc = DESCRIPTION; peer->precision = PRECISION; @@ -393,7 +392,7 @@ palisade_shutdown ( struct palisade_unit *up; struct refclockproc *pp; pp = peer->procptr; - up = (struct palisade_unit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -447,7 +446,7 @@ TSIP_decode ( struct refclockproc *pp; pp = peer->procptr; - up = (struct palisade_unit *)pp->unitptr; + up = pp->unitptr; /* * Check the time packet, decode its contents. @@ -899,7 +898,7 @@ palisade_receive ( * Initialize pointers and read the timecode and timestamp. */ pp = peer->procptr; - up = (struct palisade_unit *)pp->unitptr; + up = pp->unitptr; if (! TSIP_decode(peer)) return; @@ -964,7 +963,7 @@ palisade_poll ( struct refclockproc *pp; pp = peer->procptr; - up = (struct palisade_unit *)pp->unitptr; + up = pp->unitptr; pp->polls++; if (up->polled > 0) /* last reply never arrived or error */ @@ -1037,9 +1036,9 @@ palisade_io ( char * c, * d; - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct palisade_unit *)pp->unitptr; + up = pp->unitptr; if(up->type == CLK_PRAECIS) { if(praecis_msg) { @@ -1140,14 +1139,12 @@ HW_poll ( int x; /* state before & after RTS set */ struct palisade_unit *up; - up = (struct palisade_unit *) pp->unitptr; + up = pp->unitptr; /* read the current status, so we put things back right */ if (ioctl(pp->io.fd, TIOCMGET, &x) < 0) { -#ifdef DEBUG - if (debug) - printf("Palisade HW_poll: unit %d: GET %s\n", up->unit, strerror(errno)); -#endif + DPRINTF(1, ("Palisade HW_poll: unit %d: GET %m\n", + up->unit)); msyslog(LOG_ERR, "Palisade(%d) HW_poll: ioctl(fd,GET): %m", up->unit); return -1; @@ -1231,7 +1228,10 @@ getint ( u_char *bp ) { - return (short)ntohs(*(u_short *)bp); + u_short us; + + memcpy(&us, bp, sizeof(us)); + return (short)ntohs(us); } /* @@ -1242,7 +1242,10 @@ getlong( u_char *bp ) { - return (int32)(u_int32)ntohl(*(u_int32 *)bp); + u_int32 u32; + + memcpy(&u32, bp, sizeof(u32)); + return (int32)(u_int32)ntohl(u32); } #else /* REFCLOCK && CLOCK_PALISADE*/ diff --git a/ntpd/refclock_parse.c b/ntpd/refclock_parse.c index e222f88d6..a911a49c1 100644 --- a/ntpd/refclock_parse.c +++ b/ntpd/refclock_parse.c @@ -2651,10 +2651,10 @@ parse_shutdown( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)0; + struct parseunit *parse = NULL; if (peer && peer->procptr) - parse = (struct parseunit *)peer->procptr->unitptr; + parse = peer->procptr->unitptr; if (!parse) { @@ -2662,7 +2662,7 @@ parse_shutdown( return; } - if (!parse->peer) + if (!parse->peer) { msyslog(LOG_INFO, "PARSE receiver #%d: INTERNAL ERROR - unit already inactive - shutdown ignored", unit); return; @@ -3101,7 +3101,7 @@ parse_start( /* * pick correct input machine */ - parse->generic->io.srcclock = (caddr_t)parse; + parse->generic->io.srcclock = (void *)parse; parse->generic->io.datalen = 0; parse->binding = init_iobinding(parse); @@ -3305,7 +3305,7 @@ parse_poll( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; + struct parseunit *parse = peer->procptr->unitptr; if (peer != parse->peer) { @@ -3362,7 +3362,7 @@ parse_control( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; + struct parseunit *parse = peer->procptr->unitptr; parsectl_t tmpctl; static char outstatus[400]; /* status output buffer */ @@ -4526,7 +4526,7 @@ gps16x_poll( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; + struct parseunit *parse = peer->procptr->unitptr; static GPS_MSG_HDR sequence[] = { @@ -4668,7 +4668,7 @@ poll_poll( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; + struct parseunit *parse = peer->procptr->unitptr; if (parse->parse_type->cl_poll) parse->parse_type->cl_poll(parse); @@ -5063,7 +5063,7 @@ trimble_check( struct peer *peer ) { - struct parseunit *parse = (struct parseunit *)peer->procptr->unitptr; + struct parseunit *parse = peer->procptr->unitptr; trimble_t *t = parse->localdata; u_char buffer[256]; struct txbuf buf; diff --git a/ntpd/refclock_pcf.c b/ntpd/refclock_pcf.c index 10555160c..4379832b4 100644 --- a/ntpd/refclock_pcf.c +++ b/ntpd/refclock_pcf.c @@ -88,7 +88,7 @@ pcf_start( pp = peer->procptr; pp->io.clock_recv = noentry; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; @@ -145,7 +145,7 @@ pcf_poll( return; } - memset(&tm, 0, sizeof(tm)); + ZERO(tm); tm.tm_mday = buf[11] * 10 + buf[10]; tm.tm_mon = buf[13] * 10 + buf[12] - 1; diff --git a/ntpd/refclock_pst.c b/ntpd/refclock_pst.c index d13798b43..b3ae06181 100644 --- a/ntpd/refclock_pst.c +++ b/ntpd/refclock_pst.c @@ -135,11 +135,10 @@ pst_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = pst_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -148,7 +147,7 @@ pst_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -174,7 +173,7 @@ pst_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct pstunit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -203,9 +202,9 @@ pst_receive( /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct pstunit *)pp->unitptr; + up = pp->unitptr; up->lastptr += refclock_gtlin(rbufp, up->lastptr, pp->a_lastcode + BMAX - 2 - up->lastptr, &trtmp); *up->lastptr++ = ' '; @@ -296,7 +295,7 @@ pst_poll( * becomes unreachable, declare a timeout and keep going. */ pp = peer->procptr; - up = (struct pstunit *)pp->unitptr; + up = pp->unitptr; up->tcswitch = 0; up->lastptr = pp->a_lastcode; if (write(pp->io.fd, "QTQDQMT", 6) != 6) diff --git a/ntpd/refclock_ripencc.c b/ntpd/refclock_ripencc.c index 4796c75c8..aa619c3fd 100644 --- a/ntpd/refclock_ripencc.c +++ b/ntpd/refclock_ripencc.c @@ -504,11 +504,10 @@ ripencc_start(int unit, struct peer *peer) /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp->io.clock_recv = ripencc_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; if (!io_addclock(&pp->io)) { pp->io.fd = -1; @@ -516,7 +515,7 @@ ripencc_start(int unit, struct peer *peer) free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -650,7 +649,7 @@ ripencc_ppsapi( int capability; pp = peer->procptr; - up = (struct ripencc_unit *)pp->unitptr; + up = pp->unitptr; if (time_pps_getcap(up->handle, &capability) < 0) { msyslog(LOG_ERR, "refclock_ripencc: time_pps_getcap failed: %m"); @@ -771,7 +770,7 @@ ripencc_shutdown(int unit, struct peer *peer) struct refclockproc *pp; pp = peer->procptr; - up = (struct ripencc_unit *)pp->unitptr; + up = pp->unitptr; if (up != NULL) { if (up->handle != 0) @@ -799,7 +798,7 @@ ripencc_poll(int unit, struct peer *peer) fprintf(stderr, "ripencc_poll(%d)\n", unit); #endif /* DEBUG_NCC */ pp = peer->procptr; - up = (struct ripencc_unit *)pp->unitptr; + up = pp->unitptr; if (up->pollcnt == 0) refclock_report(peer, CEVNT_TIMEOUT); else @@ -830,7 +829,7 @@ ripencc_send(struct peer *peer, TSIPPKT spt) register struct refclockproc *pp; pp = peer->procptr; - up = (struct ripencc_unit *)pp->unitptr; + up = pp->unitptr; if (debug) printf("ripencc_send(%d, %02X)\n", up->unit, cmd); } @@ -905,9 +904,9 @@ ripencc_receive(struct recvbuf *rbufp) /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct ripencc_unit *)pp->unitptr; + up = pp->unitptr; rd_lencode = refclock_gtlin(rbufp, rd_lastcode, BMAX, &rd_tmp); #ifdef DEBUG_RAW diff --git a/ntpd/refclock_shm.c b/ntpd/refclock_shm.c index b73e89976..5d201053c 100644 --- a/ntpd/refclock_shm.c +++ b/ntpd/refclock_shm.c @@ -120,13 +120,13 @@ struct shmTime *getShmTime (int unit) { shmid=shmget (0x4e545030+unit, sizeof (struct shmTime), IPC_CREAT|(unit<2?0600:0666)); if (shmid==-1) { /*error */ - msyslog(LOG_ERR,"SHM shmget (unit %d): %s",unit,strerror(errno)); + msyslog(LOG_ERR, "SHM shmget (unit %d): %m", unit); return 0; } else { /* no error */ struct shmTime *p=(struct shmTime *)shmat (shmid, 0, 0); if ((int)(long)p==-1) { /* error */ - msyslog(LOG_ERR,"SHM shmat (unit %d): %s",unit,strerror(errno)); + msyslog(LOG_ERR, "SHM shmat (unit %d): %m", unit); return 0; } return p; @@ -189,13 +189,11 @@ shm_start( pp = peer->procptr; pp->io.clock_recv = noentry; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = -1; - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); - pp->unitptr = (caddr_t)up; + up = emalloc_zero(sizeof(*up)); up->shm = getShmTime(unit); @@ -204,6 +202,7 @@ shm_start( */ memcpy((char *)&pp->refid, REFID, 4); if (up->shm != 0) { + pp->unitptr = up; up->shm->precision = PRECISION; peer->precision = up->shm->precision; up->shm->valid=0; @@ -212,6 +211,7 @@ shm_start( return (1); } else { + free(up); return 0; } } @@ -230,7 +230,7 @@ shm_shutdown( struct shmunit *up; pp = peer->procptr; - up = (struct shmunit *)pp->unitptr; + up = pp->unitptr; if (NULL == up) return; @@ -307,7 +307,7 @@ int shm_peek( * board and tacks on a local timestamp. */ pp = peer->procptr; - up = (struct shmunit*)pp->unitptr; + up = pp->unitptr; up->ticks++; if (up->shm == 0) { /* try to map again - this may succeed if meanwhile some- @@ -400,7 +400,7 @@ void shm_clockstats( char logbuf[256]; pp = peer->procptr; - up = (struct shmunit*)pp->unitptr; + up = pp->unitptr; if (!(pp->sloppyclockflag & CLK_FLAG4)) return; diff --git a/ntpd/refclock_tpro.c b/ntpd/refclock_tpro.c index 86764d3f7..5a2255fd5 100644 --- a/ntpd/refclock_tpro.c +++ b/ntpd/refclock_tpro.c @@ -87,14 +87,13 @@ tpro_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = noentry; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous peer variables @@ -120,7 +119,7 @@ tpro_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct tprounit *)pp->unitptr; + up = pp->unitptr; io_closeclock(&pp->io); if (NULL != up) free(up); @@ -145,7 +144,7 @@ tpro_poll( * board and tacks on a local timestamp. */ pp = peer->procptr; - up = (struct tprounit *)pp->unitptr; + up = pp->unitptr; tp = &up->tprodata; if (read(pp->io.fd, (char *)tp, sizeof(struct tproval)) < 0) { diff --git a/ntpd/refclock_trak.c b/ntpd/refclock_trak.c index 6b9f7cc7e..5038ae528 100644 --- a/ntpd/refclock_trak.c +++ b/ntpd/refclock_trak.c @@ -161,11 +161,10 @@ trak_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = trak_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -174,7 +173,7 @@ trak_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -211,7 +210,7 @@ trak_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct trakunit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -249,9 +248,9 @@ trak_receive( * then chuck out everything, including runts, except one * message each poll interval. */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct trakunit *)pp->unitptr; + up = pp->unitptr; pp->lencode = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &pp->lastrec); @@ -347,7 +346,7 @@ trak_poll( * side to capture a sample and check for timeouts. */ pp = peer->procptr; - up = (struct trakunit *)pp->unitptr; + up = pp->unitptr; if (up->polled) refclock_report(peer, CEVNT_TIMEOUT); pp->polls++; diff --git a/ntpd/refclock_true.c b/ntpd/refclock_true.c index 9cde7ff87..61b70cc93 100644 --- a/ntpd/refclock_true.c +++ b/ntpd/refclock_true.c @@ -211,7 +211,7 @@ true_debug(struct peer *peer, const char *fmt, ...) va_start(ap, fmt); pp = peer->procptr; - up = (struct true_unit *)pp->unitptr; + up = pp->unitptr; want_debugging = (pp->sloppyclockflag & CLK_FLAG2) != 0; now_debugging = (up->debug != NULL); @@ -270,11 +270,10 @@ true_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = true_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -283,7 +282,7 @@ true_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -320,7 +319,7 @@ true_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct true_unit *)pp->unitptr; + up = pp->unitptr; if (pp->io.fd != -1) io_closeclock(&pp->io); if (up != NULL) @@ -351,9 +350,9 @@ true_receive( /* * Get the clock this applies to and pointers to the data. */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct true_unit *)pp->unitptr; + up = pp->unitptr; /* * Read clock output. Automatically handles STREAMS, CLKLDISC. @@ -621,7 +620,7 @@ true_doevent( struct refclockproc *pp; pp = peer->procptr; - up = (struct true_unit *)pp->unitptr; + up = pp->unitptr; if (event != e_TS) { NLOG(NLOG_CLOCKSTATUS) { msyslog(LOG_INFO, "TRUE: clock %s, state %s, event %s", @@ -842,7 +841,7 @@ true_poll( * The next time a timecode comes in, it will be fed back. */ pp = peer->procptr; - up = (struct true_unit *)pp->unitptr; + up = pp->unitptr; if (up->pollcnt > 0) up->pollcnt--; else { diff --git a/ntpd/refclock_ulink.c b/ntpd/refclock_ulink.c index c834aec42..0d48f3102 100644 --- a/ntpd/refclock_ulink.c +++ b/ntpd/refclock_ulink.c @@ -137,7 +137,7 @@ ulink_start( memset(up, 0, sizeof(struct ulinkunit)); pp = peer->procptr; pp->io.clock_recv = ulink_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -146,7 +146,7 @@ ulink_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -172,7 +172,7 @@ ulink_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct ulinkunit *)pp->unitptr; + up = pp->unitptr; if (pp->io.fd != -1) io_closeclock(&pp->io); if (up != NULL) @@ -204,9 +204,9 @@ ulink_receive( /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct ulinkunit *)pp->unitptr; + up = pp->unitptr; temp = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &trtmp); /* diff --git a/ntpd/refclock_wwv.c b/ntpd/refclock_wwv.c index b03cfe128..b6b745d6c 100644 --- a/ntpd/refclock_wwv.c +++ b/ntpd/refclock_wwv.c @@ -659,15 +659,10 @@ wwv_start( /* * Allocate and initialize unit structure */ - if (!(up = (struct wwvunit *)emalloc(sizeof(struct wwvunit)))) { - close(fd); - return (0); - } - memset(up, 0, sizeof(struct wwvunit)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; - pp->unitptr = (caddr_t)up; pp->io.clock_recv = wwv_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -675,6 +670,7 @@ wwv_start( free(up); return (0); } + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -693,8 +689,8 @@ wwv_start( for (i = 3; i < OFFSET; i++) { up->comp[i] = up->comp[i - 1] + step; up->comp[OFFSET + i] = -up->comp[i]; - if (i % 16 == 0) - step *= 2.; + if (i % 16 == 0) + step *= 2.; } DTOLFP(1. / SECOND, &up->tick); @@ -765,7 +761,7 @@ wwv_shutdown( struct wwvunit *up; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; if (up == NULL) return; @@ -803,9 +799,9 @@ wwv_receive( int bufcnt; /* buffer counter */ l_fp ltemp; - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; /* * Main loop - read until there ain't no more. Note codec @@ -884,7 +880,7 @@ wwv_poll( struct wwvunit *up; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; if (up->errflg) refclock_report(peer, up->errflg); up->errflg = 0; @@ -978,7 +974,7 @@ wwv_rf( int i; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; if (!iniflg) { iniflg = 1; @@ -1308,7 +1304,7 @@ wwv_qrz( long epoch; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; /* * Find the sample with peak amplitude, which defines the minute @@ -1409,10 +1405,10 @@ wwv_endpoc( int tmp2; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; if (!iniflg) { iniflg = 1; - memset((char *)epoch_mf, 0, sizeof(epoch_mf)); + ZERO(epoch_mf); } /* @@ -1625,7 +1621,7 @@ wwv_epoch( static double sigmin, sigzer, sigone, engmax, engmin; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; /* * Find the maximum minute sync pulse energy for both the @@ -1763,10 +1759,10 @@ wwv_rsec( int sw, arg, nsec; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; if (!iniflg) { iniflg = 1; - memset((char *)bitvec, 0, sizeof(bitvec)); + ZERO(bitvec); } /* @@ -2059,7 +2055,7 @@ wwv_clock( l_fp offset; /* offset in NTP seconds */ pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; if (!(up->status & SSYNC)) up->alarm |= SYNERR; if (up->digcnt < 9) @@ -2132,7 +2128,7 @@ wwv_corr4( int i, j; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; /* * Correlate digit vector with each BCD coefficient vector. If @@ -2225,7 +2221,7 @@ wwv_tsec( int temp; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; /* * Advance minute unit of the day. Don't propagate carries until @@ -2404,7 +2400,7 @@ wwv_newchan( int i, j, rval; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; /* * Search all five station pairs looking for the channel with @@ -2496,7 +2492,7 @@ wwv_newgame( int i; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; /* * Initialize strategic values. Note we set the leap bits @@ -2573,7 +2569,7 @@ wwv_qsy( struct wwvunit *up; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; if (up->fd_icom > 0) { up->mitig[up->achan].gain = up->gain; rval = icom_freq(up->fd_icom, peer->ttl & 0x7f, @@ -2676,7 +2672,7 @@ wwv_gain( struct wwvunit *up; pp = peer->procptr; - up = (struct wwvunit *)pp->unitptr; + up = pp->unitptr; /* * Apparently, the codec uses only the high order bits of the diff --git a/ntpd/refclock_wwvb.c b/ntpd/refclock_wwvb.c index 0daadbc13..39c75beb5 100644 --- a/ntpd/refclock_wwvb.c +++ b/ntpd/refclock_wwvb.c @@ -196,11 +196,10 @@ wwvb_start( /* * Allocate and initialize unit structure */ - up = emalloc(sizeof(*up)); - memset(up, 0, sizeof(*up)); + up = emalloc_zero(sizeof(*up)); pp = peer->procptr; pp->io.clock_recv = wwvb_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -209,7 +208,7 @@ wwvb_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -234,7 +233,7 @@ wwvb_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct wwvbunit *)pp->unitptr; + up = pp->unitptr; if (-1 != pp->io.fd) io_closeclock(&pp->io); if (NULL != up) @@ -267,9 +266,9 @@ wwvb_receive( /* * Initialize pointers and read the timecode and timestamp */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct wwvbunit *)pp->unitptr; + up = pp->unitptr; temp = refclock_gtlin(rbufp, pp->a_lastcode, BMAX, &trtmp); /* @@ -432,7 +431,7 @@ wwvb_timer( * the clock; all others just listen in. */ pp = peer->procptr; - up = (struct wwvbunit *)pp->unitptr; + up = pp->unitptr; if (up->linect > 0) pollchar = 'R'; else @@ -467,7 +466,7 @@ wwvb_poll( * are received, declare a timeout and keep going. */ pp = peer->procptr; - up = (struct wwvbunit *)pp->unitptr; + up = pp->unitptr; pp->polls++; /* @@ -526,7 +525,7 @@ wwvb_control( struct refclockproc *pp; pp = peer->procptr; - up = (struct wwvbunit *)pp->unitptr; + up = pp->unitptr; if (!(pp->sloppyclockflag & CLK_FLAG1)) { if (!up->ppsapi_tried) diff --git a/ntpd/refclock_zyfer.c b/ntpd/refclock_zyfer.c index 289586007..867159782 100644 --- a/ntpd/refclock_zyfer.c +++ b/ntpd/refclock_zyfer.c @@ -150,7 +150,7 @@ zyfer_start( memset(up, 0, sizeof(struct zyferunit)); pp = peer->procptr; pp->io.clock_recv = zyfer_receive; - pp->io.srcclock = (caddr_t)peer; + pp->io.srcclock = peer; pp->io.datalen = 0; pp->io.fd = fd; if (!io_addclock(&pp->io)) { @@ -159,7 +159,7 @@ zyfer_start( free(up); return (0); } - pp->unitptr = (caddr_t)up; + pp->unitptr = up; /* * Initialize miscellaneous variables @@ -187,7 +187,7 @@ zyfer_shutdown( struct refclockproc *pp; pp = peer->procptr; - up = (struct zyferunit *)pp->unitptr; + up = pp->unitptr; if (pp->io.fd != -1) io_closeclock(&pp->io); if (up != NULL) @@ -221,9 +221,9 @@ zyfer_receive( #endif #endif /* PPS */ - peer = (struct peer *)rbufp->recv_srcclock; + peer = rbufp->recv_peer; pp = peer->procptr; - up = (struct zyferunit *)pp->unitptr; + up = pp->unitptr; p = (u_char *) &rbufp->recv_space; /* * If lencode is 0: @@ -334,7 +334,7 @@ zyfer_poll( * side to capture a sample and check for timeouts. */ pp = peer->procptr; - up = (struct zyferunit *)pp->unitptr; + up = pp->unitptr; if (!up->pollcnt) refclock_report(peer, CEVNT_TIMEOUT); else diff --git a/ntpd/work_thread.c b/ntpd/work_thread.c deleted file mode 100644 index 1dffd936b..000000000 --- a/ntpd/work_thread.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * work_thread.c - threads implementation for blocking worker child. - */ -#include -#include "ntp_workimpl.h" - -#ifdef WORK_THREAD - -#include -#include - -#include "ntp_stdlib.h" -#include "ntp_malloc.h" -#include "ntp_syslog.h" -#include "ntpd.h" -#include "ntp_io.h" -#include "ntp_assert.h" -#include "ntp_unixtime.h" -#include "ntp_worker.h" - -#define CHILD_EXIT_REQ ((blocking_pipe_header *)(intptr_t)-1) -#define WORKITEMS_ALLOC_INC 16 -#define RESPONSES_ALLOC_INC 4 - -/* - * blocking workitems and blocking_responses are dynamically-sized - * one-dimensional arrays of pointers to blocking worker requests and - * responses. - */ -blocking_pipe_header **blocking_workitems; -size_t blocking_workitems_alloc; -size_t next_workitem; -blocking_pipe_header **blocking_responses; -size_t blocking_responses_alloc; -size_t next_response; -HANDLE blocking_child_thread; /* non-NULL when active */ -/* event handles (semaphore references) */ -HANDLE child_is_blocking; -HANDLE wake_blocking_child; -HANDLE blocking_response_ready; -HANDLE wake_scheduled_sleep; - -static void start_blocking_thread(void); -unsigned WINAPI blocking_thread(void *); -static void ensure_workitems_empty_slot(void); -static void ensure_workresp_empty_slot(void); -static int queue_req_pointer(blocking_pipe_header *); - - -void -exit_worker( - int exitcode - ) -{ - _endthreadex(exitcode); -} - - -int -worker_sleep( - time_t seconds - ) -{ - DWORD rc; - - DEBUG_REQUIRE(seconds * 1000 < MAXDWORD); - rc = WaitForSingleObject(wake_scheduled_sleep, (DWORD)seconds * 1000); - DEBUG_INSIST(WAIT_FAILED != rc); - return (WAIT_TIMEOUT == rc) - ? 0 - : -1; -} - - -void -interrupt_worker_sleep(void) -{ - SetEvent(wake_scheduled_sleep); -} - - -static void -ensure_workitems_empty_slot(void) -{ - const size_t each = sizeof(blocking_workitems[0]); - size_t new_alloc; - size_t old_octets; - size_t new_octets; - - if (blocking_workitems != NULL && - NULL == blocking_workitems[next_workitem]) - return; - - new_alloc = blocking_workitems_alloc + WORKITEMS_ALLOC_INC; - old_octets = blocking_workitems_alloc * each; - new_octets = new_alloc * each; - blocking_workitems = erealloc_zero(blocking_workitems, - new_octets, - old_octets); - if (0 == next_workitem) - next_workitem = blocking_workitems_alloc; - blocking_workitems_alloc = new_alloc; -} - - -static void -ensure_workresp_empty_slot(void) -{ - const size_t each = sizeof(blocking_responses[0]); - size_t new_alloc; - size_t old_octets; - size_t new_octets; - - if (blocking_responses != NULL && - NULL == blocking_responses[next_response]) - return; - - new_alloc = blocking_responses_alloc + RESPONSES_ALLOC_INC; - old_octets = blocking_responses_alloc * each; - new_octets = new_alloc * each; - blocking_responses = erealloc_zero(blocking_responses, - new_octets, - old_octets); - if (0 == next_response) - next_response = blocking_responses_alloc; - blocking_responses_alloc = new_alloc; -} - - -/* - * queue_req_pointer() - append a work item or idle exit request to - * blocking_workitems[]. - */ -static int -queue_req_pointer( - blocking_pipe_header * hdr - ) -{ - blocking_workitems[next_workitem] = hdr; - next_workitem = (1 + next_workitem) % blocking_workitems_alloc; - - /* - * We only want to signal the wakeup event if the child is - * blocking on it, which is indicated by setting the blocking - * event. Wait with zero timeout to test. - */ - if (WAIT_OBJECT_0 == WaitForSingleObject(child_is_blocking, 0)) - SetEvent(wake_blocking_child); - - return 0; -} - - -int -send_blocking_req_internal( - blocking_pipe_header * hdr, - void * data - ) -{ - blocking_pipe_header * threadcopy; - - DEBUG_REQUIRE(hdr != NULL); - DEBUG_REQUIRE(data != NULL); - DEBUG_REQUIRE(BLOCKING_REQ_MAGIC == hdr->magic_sig); - - ensure_workitems_empty_slot(); - if (NULL == blocking_child_thread) { - ensure_workresp_empty_slot(); - start_blocking_thread(); - } - - threadcopy = emalloc(hdr->octets); - memcpy(threadcopy, hdr, sizeof(*hdr)); - memcpy((char *)threadcopy + sizeof(*hdr), - data, hdr->octets - sizeof(*hdr)); - - return queue_req_pointer(threadcopy); -} - - -blocking_pipe_header * -receive_blocking_req_internal( - void - ) -{ - static size_t next_workeritem; - blocking_pipe_header *req; - int once; - - once = 1; - - /* we block here when idle */ - if (NULL == blocking_workitems[next_workeritem]) { - SetEvent(child_is_blocking); - while (NULL == blocking_workitems[next_workeritem]) - if (WAIT_OBJECT_0 != - WaitForSingleObject(wake_blocking_child, INFINITE)) { - DPRINTF(1, ("fatal receive_blocking_req_internal wait code\n")); - exit(-1); - } - ResetEvent(child_is_blocking); - } - - req = blocking_workitems[next_workeritem]; - blocking_workitems[next_workitem] = NULL; - next_workeritem = (1 + next_workeritem) % - blocking_workitems_alloc; - - if (CHILD_EXIT_REQ == req) /* idled out */ - req = NULL; - - return req; -} - - -int -send_blocking_resp_internal( - blocking_pipe_header *resp - ) -{ - ensure_workresp_empty_slot(); - - blocking_responses[next_response] = resp; - next_response = (1 + next_response) % blocking_responses_alloc; - - SetEvent(blocking_response_ready); - - return 0; -} - - -blocking_pipe_header * -receive_blocking_resp_internal( - void - ) -{ - static size_t next_workresp; - blocking_pipe_header * retval; - - retval = blocking_responses[next_workresp]; - - if (NULL != retval) { - blocking_responses[next_workresp] = NULL; - next_workresp = (1 + next_workresp) % - blocking_responses_alloc; - DEBUG_ENSURE(BLOCKING_RESP_MAGIC == retval->magic_sig); - } - - return retval; -} - - -static void -start_blocking_thread( - void - ) -{ - unsigned blocking_thread_id; - - /* - * create sync events (semaphores) - * child_is_blocking initially unset - * wake_blocking_child initially unset - * - * Child waits for wake_blocking_child to be set after - * setting child_is_blocking. wake_blocking_child and - * blocking_response_ready are auto-reset, so wake one - * waiter and become unset (unsignalled) in one operation. - * blocking_response_ready is created by the IO - * completion port initialization code and used before - * any blocking requests are made. - */ - if (NULL == child_is_blocking) { - /* manual reset using ResetEvent() */ - child_is_blocking = CreateEvent(NULL, TRUE, FALSE, NULL); - /* auto reset - release from wait resets it */ - wake_blocking_child = CreateEvent(NULL, FALSE, FALSE, NULL); - wake_scheduled_sleep = CreateEvent(NULL, FALSE, FALSE, NULL); - /* - * blocking_response_ready event is created in - * init_io_completion_port(), so it can be waited on - * before any blocking worker is started. - */ - } else { - ResetEvent(child_is_blocking); - ResetEvent(wake_scheduled_sleep); - ResetEvent(wake_blocking_child); - ResetEvent(blocking_response_ready); - } - - blocking_child_thread = - (HANDLE)_beginthreadex( - NULL, - 0, - blocking_thread, - NULL, - CREATE_SUSPENDED, - &blocking_thread_id); - - if (NULL == blocking_child_thread) { - DPRINTF(1, ("fatal can not start blocking thread\n")); - exit(-1); - } - /* remember the thread priority is only within the process class */ - if (!SetThreadPriority(blocking_child_thread, - THREAD_PRIORITY_BELOW_NORMAL)) { - DPRINTF(1, ("Error setting blocking thread priority\n")); - } - - ResumeThread(blocking_child_thread); - - /* wait for the child to set child_is_blocking the first time */ - while (WAIT_OBJECT_0 != WaitForSingleObject(child_is_blocking, INFINITE)) - /* null stmt */; -} - -/* - * blocking_thread - thread functions have WINAPI calling convention - */ -unsigned WINAPI -blocking_thread( - void *UnusedThreadArg - ) -{ - UNUSED_ARG(UnusedThreadArg); - - return blocking_child_common(); -} - -/* - * worker_idle_timer_fired() - * - * The parent starts this timer when the last pending response has been - * received from the child, making it idle, and clears the timer when a - * request is dispatched to the child. Once the timer expires, the - * child is sent packing. - * - * This is called when worker_idle_timer is nonzero and less than or - * equal to current_time, and is responsible for resetting - * worker_idle_timer. - * - * Note there are implementations in both work_fork.c and work_thread.c - * that should remain in sync. - */ -void -worker_idle_timer_fired(void) -{ - DEBUG_REQUIRE(0 == intres_req_pending); - - worker_idle_timer = 0; - if (NULL != blocking_child_thread) { - queue_req_pointer(CHILD_EXIT_REQ); - blocking_child_thread = NULL; - } -} - - -#else /* !WORK_THREAD follows */ -char work_thread_nonempty_compilation_unit; -#endif diff --git a/ntpdate/Makefile.am b/ntpdate/Makefile.am index a09d130e7..18e732cec 100644 --- a/ntpdate/Makefile.am +++ b/ntpdate/Makefile.am @@ -16,15 +16,16 @@ ntptimeset_SOURCES= ntptimeset.c ntptime_config.c INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include AM_CFLAGS = @CFLAGS_NTP@ AM_CPPFLAGS = @CPPFLAGS_NTP@ # LDADD might need RESLIB and ADJLIB -LDADD= version.o ../libntp/libntp.a -ntpdate_LDADD= $(LDADD) $(LIBOPTS_LDADD) $(LIBM) @LCRYPTO@ +LDADD = version.o ../libntp/libntp.a +ntpdate_LDADD = $(LDADD) @LDADD_LIBNTP@ @PTHREAD_LIBS@ $(LIBOPTS_LDADD) +ntpdate_LDADD += $(LIBM) @LCRYPTO@ DISTCLEANFILES= .version version.c stamp-v noinst_HEADERS= ntpdate.h ETAGS_ARGS= Makefile.am diff --git a/ntpdate/ntpdate.c b/ntpdate/ntpdate.c index 98f14b8a8..f3ce90d57 100644 --- a/ntpdate/ntpdate.c +++ b/ntpdate/ntpdate.c @@ -1366,6 +1366,8 @@ addserver( int error; /* Service name */ char service[5]; + sockaddr_u addr; + strncpy(service, "ntp", sizeof(service)); /* Get host address. Looking for UDP datagram connection. */ @@ -1398,16 +1400,21 @@ addserver( return; } #ifdef DEBUG - else if (debug) { - fprintf(stderr, "host found : %s\n", stohost((sockaddr_u *)addrResult->ai_addr)); + if (debug) { + ZERO(addr); + INSIST(addrResult->ai_addrlen <= sizeof(addr)); + memcpy(&addr, addrResult->ai_addr, addrResult->ai_addrlen); + fprintf(stderr, "host found : %s\n", stohost(&addr)); } #endif /* We must get all returned server in case the first one fails */ for (ptr = addrResult; ptr != NULL; ptr = ptr->ai_next) { - if (is_reachable ((sockaddr_u *)ptr->ai_addr)) { + ZERO(addr); + INSIST(ptr->ai_addrlen <= sizeof(addr)); + memcpy(&addr, ptr->ai_addr, ptr->ai_addrlen); + if (is_reachable(&addr)) { server = emalloc_zero(sizeof(*server)); - memcpy(&server->srcadr, ptr->ai_addr, ptr->ai_addrlen); server->event_time = ++sys_numservers; if (sys_servers == NULL) @@ -1683,7 +1690,9 @@ init_io(void) { struct addrinfo *res, *ressave; struct addrinfo hints; + sockaddr_u addr; char service[5]; + int rc; int optval = 1; int check_ntp_port_in_use = !debug && !simple_query && !unpriv_port; @@ -1765,13 +1774,12 @@ init_io(void) * bind the socket to the NTP port */ if (check_ntp_port_in_use) { - if (bind(fd[nbsock], res->ai_addr, - SOCKLEN((sockaddr_u *)res->ai_addr)) < 0) { -#ifndef SYS_WINNT - if (errno == EADDRINUSE) -#else - if (WSAGetLastError() == WSAEADDRINUSE) -#endif /* SYS_WINNT */ + ZERO(addr); + INSIST(res->ai_addrlen < sizeof(addr)); + memcpy(&addr, res->ai_addr, res->ai_addrlen); + rc = bind(fd[nbsock], &addr.sa, SOCKLEN(&addr)); + if (rc < 0) { + if (EADDRINUSE == socket_errno()) msyslog(LOG_ERR, "the NTP socket is in use, exiting"); else msyslog(LOG_ERR, "bind() fails: %m"); diff --git a/ntpdc/Makefile.am b/ntpdc/Makefile.am index 319713580..ebee410ea 100644 --- a/ntpdc/Makefile.am +++ b/ntpdc/Makefile.am @@ -13,7 +13,7 @@ BUILT_SOURCES= check-libntp @MAKE_CHECK_LAYOUT@ ntpdc-opts.c ntpdc-opts.h INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += $(LIBOPTS_CFLAGS) @@ -21,10 +21,11 @@ AM_CFLAGS = @CFLAGS_NTP@ AM_CPPFLAGS = @CPPFLAGS_NTP@ # LDADD might need RESLIB and ADJLIB -ntpdc_LDADD= version.o $(LIBOPTS_LDADD) ../libntp/libntp.a \ - @EDITLINE_LIBS@ @LCRYPTO@ +ntpdc_LDADD = version.o $(LIBOPTS_LDADD) ../libntp/libntp.a @LDADD_LIBNTP@ +ntpdc_LDADD += @PTHREAD_LIBS@ @EDITLINE_LIBS@ @LCRYPTO@ # ntpdc-layout doesn't need any additional libraries at all ntpdc_layout_LDADD= + DISTCLEANFILES= .version version.c CLEANFILES= check-layout layout.here nl.c ntpdc-layout noinst_HEADERS= ntpdc.h @@ -69,7 +70,7 @@ layout.here: ntpdc-layout check-layout: ntpdc-layout $(srcdir)/layout.std layout.here cmp $(srcdir)/layout.std layout.here && echo stamp > $@ -$(PROGRAMS): $(LDADD) +$(PROGRAMS): version.o check-libntp: FRC cd ../libntp && $(MAKE) diff --git a/ntpdc/layout.std b/ntpdc/layout.std index bbef64d11..6117f5215 100644 --- a/ntpdc/layout.std +++ b/ntpdc/layout.std @@ -1,3 +1,7 @@ +sizeof(union req_data_u_tag) = 176 +offsetof(u32) = 0 +offsetof(data) = 0 + sizeof(struct req_pkt) = 216 offsetof(rm_vn_mode) = 0 offsetof(auth_seq) = 1 @@ -5,7 +9,7 @@ offsetof(implementation) = 2 offsetof(request) = 3 offsetof(err_nitems) = 4 offsetof(mbz_itemsize) = 6 -offsetof(data) = 8 +offsetof(u) = 8 offsetof(tstamp) = 184 offsetof(keyid) = 192 offsetof(mac) = 196 @@ -15,6 +19,10 @@ offsetof(tstamp) = 0 offsetof(keyid) = 8 offsetof(mac) = 12 +sizeof(union resp_pkt_u_tag) = 500 +offsetof(data) = 0 +offsetof(u32) = 0 + sizeof(struct resp_pkt) = 508 offsetof(rm_vn_mode) = 0 offsetof(auth_seq) = 1 @@ -22,7 +30,7 @@ offsetof(implementation) = 2 offsetof(request) = 3 offsetof(err_nitems) = 4 offsetof(mbz_itemsize) = 6 -offsetof(data) = 8 +offsetof(u) = 8 sizeof(struct info_peer_list) = 32 offsetof(addr) = 0 diff --git a/ntpdc/nl.pl.in b/ntpdc/nl.pl.in index 813dc1f10..8007538dc 100644 --- a/ntpdc/nl.pl.in +++ b/ntpdc/nl.pl.in @@ -7,7 +7,7 @@ $debug = 0; while (<>) { next if /^#/; next if /^\s*$/; - if (/^struct req_pkt/) { + if (/^typedef union req_data_u_tag/) { $found = 1; } if (/^struct info_dns_assoc/) { @@ -20,13 +20,19 @@ while (<>) { printf " printf(\"sizeof($type) = %%d\\n\", \n\t (int) sizeof($type));\n"; next; } + if (/^typedef (union\s*\w*)\s*{\s*$/) { + $type = $1; + print STDERR "union = '$type'\n" if $debug; + printf " printf(\"sizeof($type) = %%d\\n\", \n\t (int) sizeof($type));\n"; + next; + } if (/\s*\w+\s+(\w*)\s*(\[.*\])?\s*;\s*$/) { $field = $1; print STDERR "\tfield = '$field'\n" if $debug; printf " printf(\"offsetof($field) = %%d\\n\", \n\t (int) offsetof($type, $field));\n"; next; } - if (/^}\s*;\s*$/) { + if (/^}\s*\w*\s*;\s*$/) { printf " printf(\"\\n\");\n\n"; $found = 0 if $last; next; diff --git a/ntpdc/ntpdc.c b/ntpdc/ntpdc.c index a2c8fd9f0..27fe70a7a 100644 --- a/ntpdc/ntpdc.c +++ b/ntpdc/ntpdc.c @@ -222,11 +222,6 @@ static const char *chosts[MAXHOSTS]; #define ISEOL(c) ((c) == '\n' || (c) == '\r' || (c) == '\0') #define STREQ(a, b) (*(a) == *(b) && strcmp((a), (b)) == 0) -/* - * For converting time stamps to dates - */ -#define JAN_1970 2208988800 /* 1970 - 1900 in seconds */ - /* * Jump buffer for longjumping back to the command level */ @@ -397,6 +392,8 @@ openhost( char temphost[LENHOSTNAME]; int a_info, i; struct addrinfo hints, *ai = NULL; + sockaddr_u addr; + size_t octets; register const char *cp; char name[LENHOSTNAME]; char service[5]; @@ -451,7 +448,7 @@ openhost( a_info = getaddrinfo(hname, service, &hints, &ai); } if (a_info != 0) { - (void) fprintf(stderr, "%s\n", gai_strerror(a_info)); + fprintf(stderr, "%s\n", gai_strerror(a_info)); if (ai != NULL) freeaddrinfo(ai); return 0; @@ -461,30 +458,30 @@ openhost( * getaddrinfo() has returned without error so ai should not * be NULL. */ - NTP_INSIST(ai != NULL); + INSIST(ai != NULL); + ZERO(addr); + octets = min(sizeof(addr), ai->ai_addrlen); + memcpy(&addr, ai->ai_addr, octets); - if (ai->ai_canonname == NULL) { - strncpy(temphost, stoa((sockaddr_u *)ai->ai_addr), - LENHOSTNAME); - temphost[LENHOSTNAME-1] = '\0'; - } else { - strncpy(temphost, ai->ai_canonname, LENHOSTNAME); - temphost[LENHOSTNAME-1] = '\0'; - } + if (ai->ai_canonname == NULL) + strncpy(temphost, stoa(&addr), sizeof(temphost)); + else + strncpy(temphost, ai->ai_canonname, sizeof(temphost)); + temphost[sizeof(temphost) - 1] = '\0'; if (debug > 2) - printf("Opening host %s\n", temphost); + printf("Opening host %s\n", temphost); if (havehost == 1) { if (debug > 2) - printf("Closing old host %s\n", currenthost); - (void) closesocket(sockfd); + printf("Closing old host %s\n", currenthost); + closesocket(sockfd); havehost = 0; } strncpy(currenthost, temphost, sizeof(currenthost)); /* port maps to the same in both families */ - s_port = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port; + s_port = NSRCPORT(&addr);; #ifdef SYS_VXWORKS ((struct sockaddr_in6 *)&hostaddr)->sin6_port = htons(SERVER_PORT_NUM); if (ai->ai_family == AF_INET) @@ -506,18 +503,13 @@ openhost( exit(1); } } +#endif /* SYS_WINNT */ sockfd = socket(ai->ai_family, SOCK_DGRAM, 0); if (sockfd == INVALID_SOCKET) { error("socket", "", ""); exit(-1); } -#else - sockfd = socket(ai->ai_family, SOCK_DGRAM, 0); - if (sockfd == -1) - error("socket", "", ""); -#endif /* SYS_WINNT */ - #ifdef NEED_RCVBUF_SLOP # ifdef SO_RCVBUF @@ -533,12 +525,13 @@ openhost( #ifdef SYS_VXWORKS if (connect(sockfd, (struct sockaddr *)&hostaddr, - sizeof(hostaddr)) == -1) + sizeof(hostaddr)) == -1) { #else - if (connect(sockfd, (struct sockaddr *)ai->ai_addr, - ai->ai_addrlen) == -1) + if (connect(sockfd, ai->ai_addr, ai->ai_addrlen) == -1) { #endif /* SYS_VXWORKS */ - error("connect", "", ""); + error("connect", "", ""); + exit(-1); + } freeaddrinfo(ai); havehost = 1; @@ -678,35 +671,35 @@ getresponse( */ if (n < RESP_HEADER_SIZE) { if (debug) - printf("Short (%d byte) packet received\n", n); + printf("Short (%d byte) packet received\n", n); goto again; } if (INFO_VERSION(rpkt.rm_vn_mode) > NTP_VERSION || INFO_VERSION(rpkt.rm_vn_mode) < NTP_OLDVERSION) { if (debug) - printf("Packet received with version %d\n", - INFO_VERSION(rpkt.rm_vn_mode)); + printf("Packet received with version %d\n", + INFO_VERSION(rpkt.rm_vn_mode)); goto again; } if (INFO_MODE(rpkt.rm_vn_mode) != MODE_PRIVATE) { if (debug) - printf("Packet received with mode %d\n", - INFO_MODE(rpkt.rm_vn_mode)); + printf("Packet received with mode %d\n", + INFO_MODE(rpkt.rm_vn_mode)); goto again; } if (INFO_IS_AUTH(rpkt.auth_seq)) { if (debug) - printf("Encrypted packet received\n"); + printf("Encrypted packet received\n"); goto again; } if (!ISRESPONSE(rpkt.rm_vn_mode)) { if (debug) - printf("Received request packet, wanted response\n"); + printf("Received request packet, wanted response\n"); goto again; } if (INFO_MBZ(rpkt.mbz_itemsize) != 0) { if (debug) - printf("Received packet with nonzero MBZ field!\n"); + printf("Received packet with nonzero MBZ field!\n"); goto again; } @@ -715,7 +708,7 @@ getresponse( */ if (rpkt.implementation != implcode || rpkt.request != reqcode) { if (debug) - printf( + printf( "Received implementation/request of %d/%d, wanted %d/%d", rpkt.implementation, rpkt.request, implcode, reqcode); @@ -797,7 +790,7 @@ getresponse( * items. This is so we can play nice with older implementations */ - tmp_data = rpkt.data; + tmp_data = rpkt.u.data; for (i = 0; i < items; i++) { memcpy(datap, tmp_data, (unsigned)size); tmp_data += size; @@ -871,7 +864,7 @@ sendrequest( datasize = qitems * qsize; if (datasize && qdata != NULL) { - memcpy(qpkt.data, qdata, datasize); + memcpy(qpkt.u.data, qdata, datasize); qpkt.err_nitems = ERR_NITEMS(0, qitems); qpkt.mbz_itemsize = MBZ_ITEMSIZE(qsize); } else { diff --git a/ntpdc/ntpdc_ops.c b/ntpdc/ntpdc_ops.c index 62ccce034..25aa2ee7e 100644 --- a/ntpdc/ntpdc_ops.c +++ b/ntpdc/ntpdc_ops.c @@ -709,7 +709,7 @@ again: } pl->port = (u_short)s_port; pl->hmode = pl->flags = 0; - pl = (struct info_peer_list *)((char *)pl + sendsize); + pl = (void *)((char *)pl + sendsize); } res = doquery(impl_ver, REQ_PEER_INFO, 0, qitems, @@ -722,19 +722,19 @@ again: } if (res != 0) - return; + return; if (!checkitems(items, fp)) - return; + return; if (!checkitemsize(itemsize, sizeof(struct info_peer)) && !checkitemsize(itemsize, v4sizeof(struct info_peer))) - return; + return; while (items-- > 0) { printpeer(pp, fp); if (items > 0) - (void) fprintf(fp, "\n"); + fprintf(fp, "\n"); pp++; } } @@ -785,7 +785,7 @@ again: } pl->port = (u_short)s_port; pl->hmode = plist[qitems].flags = 0; - pl = (struct info_peer_list *)((char *)pl + sendsize); + pl = (void *)((char *)pl + sendsize); } res = doquery(impl_ver, REQ_PEER_STATS, 0, qitems, @@ -799,7 +799,7 @@ again: } if (res != 0) - return; + return; if (!checkitems(items, fp)) return; @@ -1510,7 +1510,7 @@ again: SOCK_ADDR6(&pcmd->argval[qitems].netnum); pl->v6_flag = 1; } - pl = (struct conf_unpeer *)((char *)pl + sendsize); + pl = (void *)((char *)pl + sendsize); } res = doquery(impl_ver, REQ_UNCONFIG, 1, qitems, @@ -1943,6 +1943,9 @@ monlist( ) { char *struct_star; + struct info_monitor *ml; + struct info_monitor_1 *m1; + struct old_info_monitor *oml; sockaddr_u addr; sockaddr_u dstadr; int items; @@ -1950,14 +1953,13 @@ monlist( int res; int version = -1; - if (pcmd->nargs > 0) { + if (pcmd->nargs > 0) version = pcmd->argval[0].ival; - } again: res = doquery(impl_ver, (version == 1 || version == -1) ? REQ_MON_GETLIST_1 : - REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, + REQ_MON_GETLIST, 0, 0, 0, NULL, &items, &itemsize, &struct_star, (version < 0) ? (1 << INFO_ERR_REQ) : 0, sizeof(struct info_monitor_1)); @@ -1968,57 +1970,57 @@ again: } if (res == INFO_ERR_REQ && version < 0) - res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, (char *)NULL, - &items, &itemsize, &struct_star, 0, - sizeof(struct info_monitor)); + res = doquery(impl_ver, REQ_MON_GETLIST, 0, 0, 0, NULL, + &items, &itemsize, &struct_star, 0, + sizeof(struct info_monitor)); if (res != 0) - return; + return; if (!checkitems(items, fp)) - return; + return; if (itemsize == sizeof(struct info_monitor_1) || itemsize == v4sizeof(struct info_monitor_1)) { - struct info_monitor_1 *ml = (struct info_monitor_1 *) struct_star; - (void) fprintf(fp, - "remote address port local address count m ver rstr avgint lstint\n"); - (void) fprintf(fp, - "===============================================================================\n"); + m1 = (void *)struct_star; + fprintf(fp, + "remote address port local address count m ver rstr avgint lstint\n"); + fprintf(fp, + "===============================================================================\n"); while (items > 0) { - SET_ADDRS(dstadr, addr, ml, daddr, addr); + SET_ADDRS(dstadr, addr, m1, daddr, addr); if ((pcmd->nargs == 0) || - ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || - ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) + ((pcmd->argval->ival == 6) && (m1->v6_flag != 0)) || + ((pcmd->argval->ival == 4) && (m1->v6_flag == 0))) fprintf(fp, "%-22.22s %5d %-15s %8lu %1u %1u %6lx %6lu %7lu\n", nntohost(&addr), - ntohs(ml->port), + ntohs(m1->port), stoa(&dstadr), - (u_long)ntohl(ml->count), - ml->mode, - ml->version, - (u_long)ntohl(ml->restr), - (u_long)ntohl(ml->avg_int), - (u_long)ntohl(ml->last_int)); - ml++; + (u_long)ntohl(m1->count), + m1->mode, + m1->version, + (u_long)ntohl(m1->restr), + (u_long)ntohl(m1->avg_int), + (u_long)ntohl(m1->last_int)); + m1++; items--; } } else if (itemsize == sizeof(struct info_monitor) || itemsize == v4sizeof(struct info_monitor)) { - struct info_monitor *ml = (struct info_monitor *) struct_star; - (void) fprintf(fp, - " address port count mode ver rstr avgint lstint\n"); - (void) fprintf(fp, - "===============================================================================\n"); + ml = (void *) struct_star; + fprintf(fp, + " address port count mode ver rstr avgint lstint\n"); + fprintf(fp, + "===============================================================================\n"); while (items > 0) { SET_ADDR(dstadr, ml->v6_flag, ml->addr, ml->addr6); if ((pcmd->nargs == 0) || ((pcmd->argval->ival == 6) && (ml->v6_flag != 0)) || ((pcmd->argval->ival == 4) && (ml->v6_flag == 0))) - (void) fprintf(fp, + fprintf(fp, "%-25.25s %5u %9lu %4u %2u %9lx %9lu %9lu\n", nntohost(&dstadr), ntohs(ml->port), @@ -2032,21 +2034,22 @@ again: items--; } } else if (itemsize == sizeof(struct old_info_monitor)) { - struct old_info_monitor *oml = (struct old_info_monitor *)struct_star; - (void) fprintf(fp, - " address port count mode version lasttime firsttime\n"); - (void) fprintf(fp, - "======================================================================\n"); + + oml = (void *)struct_star; + fprintf(fp, + " address port count mode version lasttime firsttime\n"); + fprintf(fp, + "======================================================================\n"); while (items > 0) { SET_ADDR(dstadr, oml->v6_flag, oml->addr, oml->addr6); - (void) fprintf(fp, "%-20.20s %5u %9lu %4u %3u %9lu %9lu\n", - nntohost(&dstadr), - ntohs(oml->port), - (u_long)ntohl(oml->count), - oml->mode, - oml->version, - (u_long)ntohl(oml->lasttime), - (u_long)ntohl(oml->firsttime)); + fprintf(fp, "%-20.20s %5u %9lu %4u %3u %9lu %9lu\n", + nntohost(&dstadr), + ntohs(oml->port), + (u_long)ntohl(oml->count), + oml->mode, + oml->version, + (u_long)ntohl(oml->lasttime), + (u_long)ntohl(oml->firsttime)); oml++; items--; } @@ -2170,7 +2173,7 @@ again: SOCK_ADDR6(&pcmd->argval[qitems].netnum); pl->v6_flag = 1; } - pl = (struct conf_unpeer *)((char *)pl + sendsize); + pl = (void *)((char *)pl + sendsize); } res = doquery(impl_ver, REQ_RESET_PEER, 1, qitems, diff --git a/ntpq/Makefile.am b/ntpq/Makefile.am index 6e1db693a..6812a42d8 100644 --- a/ntpq/Makefile.am +++ b/ntpq/Makefile.am @@ -9,7 +9,7 @@ endif INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += $(LIBOPTS_CFLAGS) @@ -17,8 +17,8 @@ AM_CFLAGS = @CFLAGS_NTP@ AM_CPPFLAGS = @CPPFLAGS_NTP@ # LDADD might need RESLIB and ADJLIB -ntpq_LDADD= version.o $(LIBOPTS_LDADD) $(LIBM) ../libntp/libntp.a \ - @EDITLINE_LIBS@ @LCRYPTO@ +ntpq_LDADD = version.o $(LIBOPTS_LDADD) $(LIBM) ../libntp/libntp.a @LDADD_LIBNTP@ +ntpq_LDADD += @PTHREAD_LIBS@ @EDITLINE_LIBS@ @LCRYPTO@ noinst_HEADERS= ntpq.h noinst_LIBRARIES= libntpq.a libntpq_a_CFLAGS= -DNO_MAIN_ALLOWED -DBUILD_AS_LIB @@ -58,8 +58,6 @@ $(srcdir)/ntpq-opts.texi: $(srcdir)/ntpq-opts.def $(std_def_list) $(run_ag) -Taginfo.tpl -DLEVEL=section ntpq-opts.def $(top_srcdir)/scripts/check--help $@ -$(PROGRAMS): $(LDADD) - check-libntp: FRC cd ../libntp && $(MAKE) @@ -71,6 +69,8 @@ FRC: $(top_srcdir)/sntp/version: cd $(top_srcdir)/sntp && $(MAKE) version +$(PROGRAMS): version.o + version.o: $(ntpq_OBJECTS) ../libntp/libntp.a Makefile $(top_srcdir)/sntp/version env CSET=`cat $(top_srcdir)/sntp/version` $(top_builddir)/scripts/mkver ntpq $(COMPILE) -c version.c diff --git a/ntpq/ntpq.c b/ntpq/ntpq.c index b80794ef2..c4984c7ea 100644 --- a/ntpq/ntpq.c +++ b/ntpq/ntpq.c @@ -517,6 +517,8 @@ openhost( char temphost[LENHOSTNAME]; int a_info, i; struct addrinfo hints, *ai; + sockaddr_u addr; + size_t octets; register const char *cp; char name[LENHOSTNAME]; @@ -572,19 +574,20 @@ openhost( } #endif if (a_info != 0) { - (void) fprintf(stderr, "%s\n", gai_strerror(a_info)); + fprintf(stderr, "%s\n", gai_strerror(a_info)); return 0; } - if (ai->ai_canonname == NULL) { - strncpy(temphost, - stoa((sockaddr_u *)ai->ai_addr), - LENHOSTNAME); + INSIST(ai != NULL); + ZERO(addr); + octets = min(sizeof(addr), ai->ai_addrlen); + memcpy(&addr, ai->ai_addr, octets); - } else { - strncpy(temphost, ai->ai_canonname, LENHOSTNAME); - } - temphost[LENHOSTNAME-1] = '\0'; + if (ai->ai_canonname == NULL) + strncpy(temphost, stoa(&addr), sizeof(temphost)); + else + strncpy(temphost, ai->ai_canonname, sizeof(temphost)); + temphost[sizeof(temphost) - 1] = '\0'; if (debug > 2) printf("Opening host %s\n", temphost); @@ -592,13 +595,13 @@ openhost( if (havehost == 1) { if (debug > 2) printf("Closing old host %s\n", currenthost); - (void) closesocket(sockfd); + closesocket(sockfd); havehost = 0; } strncpy(currenthost, temphost, sizeof(currenthost)); /* port maps to the same location in both families */ - s_port = ((struct sockaddr_in6 *)ai->ai_addr)->sin6_port; + s_port = NSRCPORT(&addr); #ifdef SYS_VXWORKS ((struct sockaddr_in6 *)&hostaddr)->sin6_port = htons(SERVER_PORT_NUM); if (ai->ai_family == AF_INET) @@ -617,18 +620,21 @@ openhost( err = setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, (char *)&optionValue, sizeof(optionValue)); if (err) { - err = WSAGetLastError(); - fprintf(stderr, - "setsockopt(SO_SYNCHRONOUS_NONALERT) " - "error: %s\n", strerror(err)); + mfprintf(stderr, + "setsockopt(SO_SYNCHRONOUS_NONALERT)" + " error: %m\n"); + freeaddrinfo(ai); exit(1); } } #endif /* SYS_WINNT */ - sockfd = socket(ai->ai_family, SOCK_DGRAM, 0); + sockfd = socket(ai->ai_family, ai->ai_socktype, + ai->ai_protocol); if (sockfd == INVALID_SOCKET) { error("socket", "", ""); + freeaddrinfo(ai); + return 0; } @@ -637,21 +643,23 @@ openhost( { int rbufsize = DATASIZE + 2048; /* 2K for slop */ if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &rbufsize, sizeof(int)) == -1) - error("setsockopt", "", ""); + error("setsockopt", "", ""); } # endif #endif #ifdef SYS_VXWORKS if (connect(sockfd, (struct sockaddr *)&hostaddr, - sizeof(hostaddr)) == -1) + sizeof(hostaddr)) == -1) { #else if (connect(sockfd, (struct sockaddr *)ai->ai_addr, - ai->ai_addrlen) == -1) + ai->ai_addrlen) == -1) { #endif /* SYS_VXWORKS */ - error("connect", "", ""); - if (a_info == 0) + error("connect", "", ""); freeaddrinfo(ai); + return 0; + } + freeaddrinfo(ai); havehost = 1; numassoc = 0; @@ -1053,7 +1061,7 @@ getresponse( /* * Copy the data into the data buffer. */ - memcpy((char *)pktdata + offset, rpkt.data, count); + memcpy((char *)pktdata + offset, &rpkt.u, count); /* * If we've seen the last fragment, look for holes in the sequence. @@ -1122,10 +1130,10 @@ sendrequest( * If we have data, copy and pad it out to a 32-bit boundary. */ if (qsize > 0) { - memcpy(qpkt.data, qdata, (size_t)qsize); + memcpy(&qpkt.u, qdata, (size_t)qsize); pktsize += qsize; while (pktsize & (sizeof(u_int32) - 1)) { - qpkt.data[qsize++] = 0; + qpkt.u.data[qsize++] = 0; pktsize++; } } @@ -1143,7 +1151,7 @@ sendrequest( * receiver can handle it. */ while (pktsize & 7) { - qpkt.data[qsize++] = 0; + qpkt.u.data[qsize++] = 0; pktsize++; } @@ -1717,7 +1725,7 @@ getnetnum( LENHOSTNAME, NULL, 0, 0); return 1; } else if (getaddrinfo(hname, "ntp", &hints, &ai) == 0) { - NTP_INSIST(sizeof(*num) >= ai->ai_addrlen); + INSIST(sizeof(*num) >= ai->ai_addrlen); memcpy(num, ai->ai_addr, ai->ai_addrlen); if (fullhost != NULL) { if (ai->ai_canonname != NULL) @@ -1728,6 +1736,7 @@ getnetnum( fullhost, LENHOSTNAME, NULL, 0, 0); } + freeaddrinfo(ai); return 1; } fprintf(stderr, "***Can't find host %s\n", hname); diff --git a/ntpsnmpd/Makefile.am b/ntpsnmpd/Makefile.am index 5c2981ebb..4a978b447 100644 --- a/ntpsnmpd/Makefile.am +++ b/ntpsnmpd/Makefile.am @@ -12,12 +12,13 @@ ntpsnmpd_SOURCES= netsnmp_daemonize.c ntpsnmpd.c ntpSnmpSubagentObject.c \ ntpsnmpd-opts.c ntpsnmpd-opts.h ntpSnmpSubagentObject.h \ ntp_snmp.h # HMS: we probably want a version.o file here, too. -LDADD= ../ntpq/libntpq.a ../libntp/libntp.a @LCRYPTO@ @SNMP_LIBS@ \ - $(LIBOPTS_LDADD) +LDADD = ../ntpq/libntpq.a ../libntp/libntp.a @LDADD_LIBNTP@ @PTHREAD_LIBS@ @LCRYPTO@ +LDADD += @SNMP_LIBS@ $(LIBOPTS_LDADD) -INCLUDES = -I$(top_srcdir)/ntpq -I$(top_srcdir)/include +INCLUDES = -I$(top_srcdir)/ntpq +INCLUDES += -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += $(LIBOPTS_CFLAGS) INCLUDES += @SNMP_CPPFLAGS@ diff --git a/parseutil/Makefile.am b/parseutil/Makefile.am index 3dc7dc157..d428146e4 100644 --- a/parseutil/Makefile.am +++ b/parseutil/Makefile.am @@ -6,12 +6,14 @@ CLEANFILES = noinst_PROGRAMS = @TESTDCF@ @DCFD@ EXTRA_PROGRAMS = testdcf dcfd -INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/lib/isc/include \ - -I$(top_srcdir)/lib/isc/nothreads/include \ - -I$(top_srcdir)/lib/isc/unix/include +INCLUDES = -I$(top_srcdir)/include +INCLUDES += -I$(top_srcdir)/lib/isc/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include +INCLUDES += -I$(top_srcdir)/lib/isc/unix/include AM_CFLAGS = @CFLAGS_NTP@ AM_CPPFLAGS = @CPPFLAGS_NTP@ +LDADD = @LDADD_LIBNTP@ ETAGS_ARGS = Makefile.am DISTCLEANFILES = $(EXTRA_PROGRAMS) diff --git a/ports/winnt/include/ntp_iocompletionport.h b/ports/winnt/include/ntp_iocompletionport.h index 0e381cdaf..a32476f98 100644 --- a/ports/winnt/include/ntp_iocompletionport.h +++ b/ports/winnt/include/ntp_iocompletionport.h @@ -4,6 +4,7 @@ #include "ntp_fp.h" #include "ntp.h" #include "clockstuff.h" +#include "ntp_worker.h" # if defined(HAVE_IO_COMPLETION_PORT) @@ -16,11 +17,10 @@ struct refclockio; /* in ntp_refclock.h but inclusion here triggers problems */ extern int io_completion_port_add_clock_io(struct refclockio *rio); extern int io_completion_port_sendto(int, void *, size_t, sockaddr_u *); -extern HANDLE get_io_event(void); -extern HANDLE get_exit_event(void); - extern int GetReceivedBuffers(void); +extern HANDLE WaitableExitEventHandle; + # endif #endif diff --git a/ports/winnt/include/ntp_timer.h b/ports/winnt/include/ntp_timer.h index a4023b23f..15328a67a 100644 --- a/ports/winnt/include/ntp_timer.h +++ b/ports/winnt/include/ntp_timer.h @@ -3,8 +3,4 @@ extern void timer_clr_stats(void); -#ifdef SYS_WINNT -extern HANDLE get_timer_handle(void); -#endif - #endif /* NTP_TIMER_H */ diff --git a/ports/winnt/libntp/win32_io.c b/ports/winnt/libntp/win32_io.c index 9bc0a665a..52dcbeb96 100644 --- a/ports/winnt/libntp/win32_io.c +++ b/ports/winnt/libntp/win32_io.c @@ -36,9 +36,10 @@ InitSockets( err = WSAStartup(wVersionRequested, &wsaData); if ( err != 0 ) { - fprintf(stderr, "No useable winsock.dll: %s\n", strerror(err)); SetLastError(err); - msyslog(LOG_ERR, "No usable winsock.dll: %m"); + mfprintf(stderr, "No usable winsock: %m\n"); + SetLastError(err); + msyslog(LOG_ERR, "No usable winsock: %m\n"); exit(1); } } diff --git a/ports/winnt/ntpd/ntp_iocompletionport.c b/ports/winnt/ntpd/ntp_iocompletionport.c index 7821ffb42..e2ff0fbff 100644 --- a/ports/winnt/ntpd/ntp_iocompletionport.c +++ b/ports/winnt/ntpd/ntp_iocompletionport.c @@ -9,19 +9,13 @@ #include #include -#include "ntp_stdlib.h" -#include "ntp_machine.h" -#include "ntp_fp.h" -#include "ntp.h" #include "ntpd.h" -#include "ntp_refclock.h" +#include "ntp_machine.h" #include "ntp_iocompletionport.h" #include "ntp_request.h" #include "ntp_assert.h" -#include "clockstuff.h" #include "ntp_io.h" #include "ntp_lists.h" -#include "clockstuff.h" #define CONTAINEROF(p, type, member) \ @@ -63,24 +57,28 @@ typedef struct olplus_tag { /* * local function definitions */ -static int QueueSerialWait(struct refclockio *, recvbuf_t *buff, - olplus *lpo, BOOL clear_timestamp); -static int QueueRawSerialRead(struct refclockio *, recvbuf_t *buff, - olplus *lpo); + void ntpd_addremove_semaphore(HANDLE, int); +static int QueueSerialWait(struct refclockio *, recvbuf_t *buff, + olplus *lpo, BOOL clear_timestamp); +static int QueueRawSerialRead(struct refclockio *, recvbuf_t *buff, + olplus *lpo); +static int OnSocketRecv(ULONG_PTR, olplus *, DWORD, int); +static int OnSerialWaitComplete(struct refclockio *, olplus *, + DWORD, int); +static int OnSerialReadComplete(struct refclockio *, olplus *, + DWORD, int); +static int OnRawSerialReadComplete(struct refclockio *, olplus *, + DWORD, int); +static int OnWriteComplete(ULONG_PTR, olplus *, DWORD, int); -static int OnSocketRecv(ULONG_PTR, olplus *, DWORD, int); -static int OnSerialWaitComplete(struct refclockio *, olplus *, DWORD, int); -static int OnSerialReadComplete(struct refclockio *, olplus *, DWORD, int); -static int OnRawSerialReadComplete(struct refclockio *, olplus *, DWORD, int); -static int OnWriteComplete(ULONG_PTR, olplus *, DWORD, int); /* keep a list to traverse to free memory on debug builds */ #ifdef DEBUG static void free_io_completion_port_mem(void); -olplus * compl_info_list; +olplus * compl_info_list; CRITICAL_SECTION compl_info_lock; -#define LOCK_COMPL() EnterCriticalSection(&compl_info_lock); -#define UNLOCK_COMPL() LeaveCriticalSection(&compl_info_lock); +#define LOCK_COMPL() EnterCriticalSection(&compl_info_lock) +#define UNLOCK_COMPL() LeaveCriticalSection(&compl_info_lock) #endif /* #define USE_HEAP */ @@ -89,10 +87,9 @@ CRITICAL_SECTION compl_info_lock; static HANDLE hHeapHandle = NULL; #endif -static HANDLE hIoCompletionPort = NULL; - -static HANDLE WaitableIoEventHandle = NULL; -static HANDLE WaitableExitEventHandle = NULL; + HANDLE WaitableExitEventHandle; +static HANDLE hIoCompletionPort = NULL; +static HANDLE WaitableIoEventHandle = NULL; #ifdef NTPNEEDNAMEDHANDLE #define WAITABLEIOEVENTHANDLE "WaitableIoEventHandle" @@ -100,8 +97,8 @@ static HANDLE WaitableExitEventHandle = NULL; #define WAITABLEIOEVENTHANDLE NULL #endif -#define MAXHANDLES 4 -HANDLE WaitHandles[MAXHANDLES]; +DWORD ActiveWaitHandles; +HANDLE WaitHandles[16]; olplus * GetHeapAlloc(char *fromfunc) @@ -147,18 +144,6 @@ FreeHeap(olplus *lpo, char *fromfunc) #endif } -HANDLE -get_io_event(void) -{ - return( WaitableIoEventHandle ); -} - -HANDLE -get_exit_event(void) -{ - return( WaitableExitEventHandle ); -} - /* This function will add an entry to the I/O completion port * that will signal the I/O thread to exit (gracefully) */ @@ -316,17 +301,25 @@ init_io_completion_port( exit(1); } - blocking_response_ready = CreateEvent(NULL, FALSE, FALSE, NULL); /* * Initialize the Wait Handles */ WaitHandles[0] = WaitableIoEventHandle; WaitHandles[1] = WaitableExitEventHandle; /* exit request */ - WaitHandles[2] = get_timer_handle(); - WaitHandles[3] = blocking_response_ready; + WaitHandles[2] = WaitableTimerHandle; + ActiveWaitHandles = 3; - /* Have one thread servicing I/O - there were 4, but this would + /* + * Supply ntp_worker.c with function to add or remove a + * semaphore to the ntpd I/O loop which is signalled by a worker + * when a response is ready. The callback is invoked in the + * parent. + */ + addremove_io_semaphore = &ntpd_addremove_semaphore; + + /* + * Have one thread servicing I/O - there were 4, but this would * somehow cause NTP to stop replying to ntpq requests; TODO */ thread = (HANDLE)_beginthreadex( @@ -339,7 +332,41 @@ init_io_completion_port( ResumeThread(thread); CloseHandle(thread); } - + + +void +ntpd_addremove_semaphore( + HANDLE sem, + int remove + ) +{ + const size_t hnd_sz = sizeof(WaitHandles[0]); + u_int hi; + + if (!remove) { + INSIST((ActiveWaitHandles + 1) < COUNTOF(WaitHandles)); + WaitHandles[ActiveWaitHandles] = sem; + ActiveWaitHandles++; + + return; + } + + /* removing semaphore */ + for (hi = 3; hi < ActiveWaitHandles; hi++) + if (sem == WaitHandles[hi]) + break; + + if (hi == ActiveWaitHandles) + return; + + ActiveWaitHandles--; + if (hi < ActiveWaitHandles) + memmove(&WaitHandles[hi], + &WaitHandles[hi + 1], + (ActiveWaitHandles - hi) * hnd_sz); + WaitHandles[ActiveWaitHandles] = NULL; +} + #ifdef DEBUG static void @@ -369,7 +396,7 @@ free_io_completion_port_mem( FreeHeap(pci, "free_io_completion_port_mem"); /* FreeHeap() removed this item from compl_info_list */ } - UNLOCK_COMPL() + UNLOCK_COMPL(); #if defined(_MSC_VER) && defined (_DEBUG) _CrtCheckMemory(); @@ -1018,37 +1045,49 @@ async_write( */ int GetReceivedBuffers() { - isc_boolean_t have_packet = ISC_FALSE; + DWORD index; + HANDLE ready; + int have_packet; + + have_packet = FALSE; while (!have_packet) { - DWORD Index = WaitForMultipleObjects(MAXHANDLES, WaitHandles, FALSE, INFINITE); - switch (Index) { + index = WaitForMultipleObjects(ActiveWaitHandles, + WaitHandles, FALSE, + INFINITE); + switch (index) { + case WAIT_OBJECT_0 + 0: /* Io event */ DPRINTF(4, ("IoEvent occurred\n")); - have_packet = ISC_TRUE; + have_packet = TRUE; break; + case WAIT_OBJECT_0 + 1: /* exit request */ exit(0); break; + case WAIT_OBJECT_0 + 2: /* timer */ timer(); break; - case WAIT_OBJECT_0 + 3: /* blocking response */ - process_blocking_response(); - break; + case WAIT_IO_COMPLETION: /* loop */ break; + case WAIT_TIMEOUT: msyslog(LOG_ERR, "ntpd: WaitForMultipleObjects INFINITE timed out."); exit(1); break; + case WAIT_FAILED: msyslog(LOG_ERR, "ntpd: WaitForMultipleObjects Failed: Error: %m"); exit(1); break; - /* For now do nothing if not expected */ default: - break; + DEBUG_INSIST((index - WAIT_OBJECT_0) < + ActiveWaitHandles); + ready = WaitHandles[index - WAIT_OBJECT_0]; + handle_blocking_resp_sem(ready); + break; } /* switch */ } diff --git a/ports/winnt/ntpd/ntservice.c b/ports/winnt/ntpd/ntservice.c index 63fa47345..af76201e3 100644 --- a/ports/winnt/ntpd/ntservice.c +++ b/ports/winnt/ntpd/ntservice.c @@ -226,21 +226,21 @@ ntservice_exit( void ) * to the service. */ void WINAPI -ServiceControl(DWORD dwCtrlCode) { - /* Handle the requested control code */ - HANDLE exitEvent = get_exit_event(); - - switch(dwCtrlCode) { +ServiceControl( + DWORD dwCtrlCode + ) +{ + switch (dwCtrlCode) { case SERVICE_CONTROL_SHUTDOWN: computer_shutting_down = TRUE; /* fall through to stop case */ case SERVICE_CONTROL_STOP: - if (exitEvent != NULL) { - SetEvent(exitEvent); + if (WaitableExitEventHandle != NULL) { + SetEvent(WaitableExitEventHandle); UpdateSCM(SERVICE_STOP_PENDING); - Sleep( 100 ); //##++ + Sleep(100); //##++ } return; @@ -283,8 +283,6 @@ OnConsoleEvent( DWORD dwCtrlType ) { - HANDLE exitEvent = get_exit_event(); - switch (dwCtrlType) { #ifdef DEBUG case CTRL_BREAK_EVENT: @@ -307,9 +305,9 @@ OnConsoleEvent( case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: case CTRL_SHUTDOWN_EVENT: - if (exitEvent != NULL) { - SetEvent(exitEvent); - Sleep( 100 ); //##++ + if (WaitableExitEventHandle != NULL) { + SetEvent(WaitableExitEventHandle); + Sleep(100); //##++ } break; diff --git a/ports/winnt/vc6/libntp.dsp b/ports/winnt/vc6/libntp.dsp index f791695c3..5577556be 100644 --- a/ports/winnt/vc6/libntp.dsp +++ b/ports/winnt/vc6/libntp.dsp @@ -326,6 +326,10 @@ SOURCE=..\..\..\libntp\ntp_calendar.c # End Source File # Begin Source File +SOURCE=..\..\..\libntp\ntp_intres.c +# End Source File +# Begin Source File + SOURCE=..\..\..\libntp\ntp_libopts.c # End Source File # Begin Source File @@ -342,6 +346,10 @@ SOURCE=..\..\..\libntp\ntp_rfc2553.c # End Source File # Begin Source File +SOURCE=..\..\..\libntp\ntp_worker.c +# End Source File +# Begin Source File + SOURCE=..\..\..\libntp\numtoa.c # End Source File # Begin Source File @@ -474,6 +482,14 @@ SOURCE=..\..\..\lib\isc\win32\win32os.c # End Source File # Begin Source File +SOURCE=..\..\..\libntp\work_fork.c +# End Source File +# Begin Source File + +SOURCE=..\..\..\libntp\work_thread.c +# End Source File +# Begin Source File + SOURCE=..\..\..\libntp\ymd2yd.c # End Source File # End Group @@ -510,6 +526,10 @@ SOURCE=..\include\arpa\inet.h # End Source File # Begin Source File +SOURCE=..\..\..\include\intreswork.h +# End Source File +# Begin Source File + SOURCE=..\include\inttypes.h # End Source File # Begin Source File @@ -586,6 +606,10 @@ SOURCE=..\include\ntp_iocompletionport.h # End Source File # Begin Source File +SOURCE=..\..\..\include\ntp_intres.h +# End Source File +# Begin Source File + SOURCE=..\..\..\include\ntp_lineedit.h # End Source File # Begin Source File diff --git a/ports/winnt/vc6/ntpd.dsp b/ports/winnt/vc6/ntpd.dsp index 090bb0083..a5c317b64 100644 --- a/ports/winnt/vc6/ntpd.dsp +++ b/ports/winnt/vc6/ntpd.dsp @@ -118,11 +118,6 @@ SOURCE=..\..\..\ntpd\ntp_filegen.c # End Source File # Begin Source File -SOURCE=..\..\..\ntpd\ntp_intres.c -# SUBTRACT CPP /YX -# End Source File -# Begin Source File - SOURCE=..\..\..\ntpd\ntp_io.c # SUBTRACT CPP /YX # End Source File @@ -186,11 +181,6 @@ SOURCE=..\..\..\ntpd\ntp_util.c # End Source File # Begin Source File -SOURCE=..\..\..\ntpd\ntp_worker.c -# SUBTRACT CPP /YX -# End Source File -# Begin Source File - SOURCE="..\..\..\ntpd\ntpd-opts.c" # End Source File # Begin Source File @@ -203,16 +193,6 @@ SOURCE=..\..\..\ntpd\ntpd.c SOURCE=..\ntpd\ntservice.c # SUBTRACT CPP /YX # End Source File -# Begin Source File - -SOURCE=..\..\..\ntpd\work_fork.c -# SUBTRACT CPP /YX -# End Source File -# Begin Source File - -SOURCE=..\..\..\ntpd\work_thread.c -# SUBTRACT CPP /YX -# End Source File # PROP Default_Filter "h;hpp;hxx;hm;inl" # Begin Source File diff --git a/ports/winnt/vs2003/libntp.vcproj b/ports/winnt/vs2003/libntp.vcproj index 8a7b31135..cd08e11b5 100644 --- a/ports/winnt/vs2003/libntp.vcproj +++ b/ports/winnt/vs2003/libntp.vcproj @@ -1207,24 +1207,9 @@ - - - - - - + + @@ -1252,66 +1237,15 @@ - - - - - - - - - - - - + + - - - - - - @@ -1851,26 +1785,14 @@ PreprocessorDefinitions=""/> + + + + - - - - - - + + @@ -1966,6 +1891,9 @@ + + diff --git a/ports/winnt/vs2003/ntpd.vcproj b/ports/winnt/vs2003/ntpd.vcproj index ebe615046..cb042b60c 100644 --- a/ports/winnt/vs2003/ntpd.vcproj +++ b/ports/winnt/vs2003/ntpd.vcproj @@ -279,29 +279,6 @@ BrowseInformation="1"/> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - - - - + + @@ -2157,6 +773,10 @@ RelativePath="..\include\ntp_timer.h" > + + diff --git a/ports/winnt/vs2005/ntpd.vcproj b/ports/winnt/vs2005/ntpd.vcproj index 8d5a85e49..625a31751 100644 --- a/ports/winnt/vs2005/ntpd.vcproj +++ b/ports/winnt/vs2005/ntpd.vcproj @@ -338,28 +338,6 @@ /> - - - - - - - - @@ -646,10 +624,6 @@ /> - - @@ -716,14 +690,6 @@ /> - - - - + + @@ -431,6 +435,10 @@ RelativePath="..\..\..\..\libntp\ntp_rfc2553.c" > + + @@ -579,6 +587,14 @@ RelativePath="..\..\..\..\lib\isc\win32\win32os.c" > + + + + @@ -640,6 +656,10 @@ RelativePath="..\..\..\..\lib\isc\include\isc\interfaceiter.h" > + + @@ -672,6 +692,10 @@ RelativePath="..\..\..\..\include\isc\mem.h" > + + @@ -716,6 +740,10 @@ RelativePath="..\..\..\..\include\ntp_if.h" > + + @@ -853,11 +881,11 @@ > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - - - - - - #endif - ]], - [[ - struct ip_mreq ipmr; - ipmr.imr_interface.s_addr = 0; - ]] - )], - [ntp_cv_multicast=yes], - [] - ) - esac - ] -) -case "$ntp_cv_multicast" in - yes) - AC_DEFINE([MCAST], [1], [Does the target support multicast IP?]) - AC_CACHE_CHECK( - [arg type needed for setsockopt() IP*_MULTICAST_LOOP], - [ntp_cv_typeof_ip_multicast_loop], - [ - case "$host" in - *-*-netbsd*|*-*-*linux*) - ntp_cv_typeof_ip_multicast_loop=u_int - ;; - *) - ntp_cv_typeof_ip_multicast_loop=u_char - esac - ] - ) - AC_DEFINE_UNQUOTED([TYPEOF_IP_MULTICAST_LOOP], - $ntp_cv_typeof_ip_multicast_loop, - [What type to use for setsockopt]) -esac - -# HMS: We don't need res_init, but since we may be using cached -# values from ntpd we need to test the same way -AC_SEARCH_LIBS([res_init], [resolv], , , [-lsocket -lnsl]) -AC_SEARCH_LIBS([inet_ntop], [resolv], , , [-lsocket -lnsl]) -AC_CHECK_FUNC([inet_ntop], [], - [AC_DEFINE([ISC_PLATFORM_NEEDNTOP], [1], [ISC: provide inet_ntop()])]) -AC_CHECK_FUNC([inet_pton], [], - [AC_DEFINE([ISC_PLATFORM_NEEDPTON], [1], [ISC: provide inet_pton()])]) - ### # Hacks @@ -182,14 +105,7 @@ AC_CHECK_FUNCS([socket vsnprintf vsprintf]) AC_PROG_CXX NTP_GOOGLETEST -case "$NEED_LIBEVENT_DIR" in - true) - AC_CONFIG_SUBDIRS([libevent]) - ;; -esac - AC_CONFIG_FILES([Makefile]) -AC_CONFIG_FILES(build-libevent/Makefile) AC_CONFIG_FILES([include/Makefile]) AC_CONFIG_FILES([tests/Makefile]) diff --git a/sntp/deps-ver b/sntp/deps-ver index 83750ad1b..596602f02 100644 --- a/sntp/deps-ver +++ b/sntp/deps-ver @@ -1 +1 @@ -Sat Jan 8 18:11:35 UTC 2011 +Mon Jan 31 21:14:29 UTC 2011 diff --git a/sntp/kod_management.c b/sntp/kod_management.c index d98204e40..0a26854e1 100644 --- a/sntp/kod_management.c +++ b/sntp/kod_management.c @@ -7,6 +7,7 @@ #include "log.h" #include "sntp-opts.h" #include "ntp_stdlib.h" +#include "ntp_worker.h" #include "ntp_debug.h" int kod_init = 0, kod_db_cnt = 0; @@ -18,7 +19,7 @@ struct kod_entry **kod_db; /* array of pointers to kod_entry */ * Search for a KOD entry */ int -search_entry ( +search_entry( const char *hostname, struct kod_entry **dst ) @@ -56,7 +57,7 @@ add_entry( int n; struct kod_entry *pke; - pke = emalloc(sizeof(*pke)); + pke = emalloc_zero(sizeof(*pke)); pke->timestamp = time(NULL); memcpy(pke->type, type, 4); pke->type[sizeof(pke->type) - 1] = '\0'; @@ -113,6 +114,17 @@ delete_entry( void +atexit_write_kod_db(void) +{ +#ifdef WORK_FORK + if (worker_process) + return; +#endif + write_kod_db(); +} + + +int write_kod_db(void) { FILE *db_s; @@ -144,7 +156,7 @@ write_kod_db(void) msyslog(LOG_WARNING, "Can't open KOD db file %s for writing!", kod_db_file); - return; + return FALSE; } for (a = 0; a < kod_db_cnt; a++) { @@ -155,12 +167,15 @@ write_kod_db(void) fflush(db_s); fclose(db_s); + + return TRUE; } void kod_init_kod_db( - const char *db_file + const char * db_file, + int readonly ) { /* @@ -174,13 +189,10 @@ kod_init_kod_db( char *str_ptr; char error = 0; - atexit(write_kod_db); - DPRINTF(2, ("Initializing KOD DB...\n")); kod_db_file = estrdup(db_file); - db_s = fopen(db_file, "r"); if (NULL == db_s) { @@ -224,8 +236,7 @@ kod_init_kod_db( if (0 == kod_db_cnt) { DPRINTF(2, ("KoD DB %s empty.\n", db_file)); - fclose(db_s); - return; + goto wrapup; } DPRINTF(2, ("KoD DB %s contains %d entries, reading...\n", db_file, kod_db_cnt)); @@ -274,11 +285,14 @@ kod_init_kod_db( return; } + wrapup: fclose(db_s); - if (debug > 1) - for (a = 0; a < kod_db_cnt; a++) - printf("KoD entry %d: %s at %llx type %s\n", a, - kod_db[a]->hostname, - (unsigned long long)kod_db[a]->timestamp, - kod_db[a]->type); + for (a = 0; a < kod_db_cnt; a++) + DPRINTF(2, ("KoD entry %d: %s at %llx type %s\n", a, + kod_db[a]->hostname, + (unsigned long long)kod_db[a]->timestamp, + kod_db[a]->type)); + + if (!readonly && write_kod_db()) + atexit(&atexit_write_kod_db); } diff --git a/sntp/kod_management.h b/sntp/kod_management.h index 63e68ab57..37089f209 100644 --- a/sntp/kod_management.h +++ b/sntp/kod_management.h @@ -12,8 +12,9 @@ struct kod_entry { int search_entry(const char *hostname, struct kod_entry **dst); void add_entry(const char *hostname, const char *type); void delete_entry(const char *hostname, const char *type); -void kod_init_kod_db(const char *db_file); -void write_kod_db(void); +void kod_init_kod_db(const char *db_file, int readonly); +int write_kod_db(void); +void atexit_write_kod_db(void); #endif diff --git a/sntp/libevent/Makefile.am b/sntp/libevent/Makefile.am index 46f6d34e1..498ef9728 100644 --- a/sntp/libevent/Makefile.am +++ b/sntp/libevent/Makefile.am @@ -72,7 +72,7 @@ VERSION_INFO = 5:1:0 dist_bin_SCRIPTS = event_rpcgen.py pkgconfigdir=$(libdir)/pkgconfig -pkgconfig_DATA=libevent.pc +LIBEVENT_PKGCONFIG=libevent.pc # These sources are conditionally added by configure.in or conditionally # included from other files. @@ -87,16 +87,24 @@ EXTRA_DIST = \ Doxyfile \ whatsnew-2.0.txt \ Makefile.nmake test/Makefile.nmake \ + m4/LICENSE-OPENLDAP \ $(PLATFORM_DEPENDENT_SRC) -lib_LTLIBRARIES = libevent.la libevent_core.la libevent_extra.la +LIBEVENT_LIBS_LA = libevent.la libevent_core.la libevent_extra.la if PTHREADS -lib_LTLIBRARIES += libevent_pthreads.la -pkgconfig_DATA += libevent_pthreads.pc +LIBEVENT_LIBS_LA += libevent_pthreads.la +LIBEVENT_PKGCONFIG += libevent_pthreads.pc endif if OPENSSL -lib_LTLIBRARIES += libevent_openssl.la -pkgconfig_DATA += libevent_openssl.pc +LIBEVENT_LIBS_LA += libevent_openssl.la +LIBEVENT_PKGCONFIG += libevent_openssl.pc +endif + +if INSTALL_LIBEVENT +lib_LTLIBRARIES = $(LIBEVENT_LIBS_LA) +pkgconfig_DATA = $(LIBEVENT_PKGCONFIG) +else +noinst_LTLIBRARIES = $(LIBEVENT_LIBS_LA) endif SUBDIRS = . include sample test diff --git a/sntp/libevent/WIN32-Code/event2/event-config.h b/sntp/libevent/WIN32-Code/event2/event-config.h index 8a4410746..fa14ae94c 100644 --- a/sntp/libevent/WIN32-Code/event2/event-config.h +++ b/sntp/libevent/WIN32-Code/event2/event-config.h @@ -274,7 +274,7 @@ /* #undef _EVENT_HAVE_WORKING_KQUEUE */ /* Numeric representation of the version */ -#define _EVENT_NUMERIC_VERSION 0x02000a00 +#define _EVENT_NUMERIC_VERSION 0x02000a01 /* Name of package */ #define _EVENT_PACKAGE "libevent" @@ -331,7 +331,7 @@ #define _EVENT_TIME_WITH_SYS_TIME 1 /* Version number of package */ -#define _EVENT_VERSION "2.0.10-stable" +#define _EVENT_VERSION "2.0.10-stable-dev" /* Define to appropriate substitue if compiler doesnt have __func__ */ #define _EVENT___func__ __FUNCTION__ diff --git a/sntp/libevent/arc4random.c b/sntp/libevent/arc4random.c index b6d2c5b33..4833169a2 100644 --- a/sntp/libevent/arc4random.c +++ b/sntp/libevent/arc4random.c @@ -352,7 +352,7 @@ arc4_seed(void) return ok ? 0 : -1; } -static void +static int arc4_stir(void) { int i; @@ -363,6 +363,8 @@ arc4_stir(void) } arc4_seed(); + if (!arc4_seeded_ok) + return -1; /* * Discard early keystream, as per recommendations in @@ -385,6 +387,8 @@ arc4_stir(void) for (i = 0; i < 12*256; i++) (void)arc4_getbyte(); arc4_count = BYTES_BEFORE_RESEED; + + return 0; } diff --git a/sntp/libevent/configure.in b/sntp/libevent/configure.in index 7b8f2af64..e11562761 100644 --- a/sntp/libevent/configure.in +++ b/sntp/libevent/configure.in @@ -5,15 +5,29 @@ AC_INIT(event.c) AC_CONFIG_MACRO_DIR([m4]) -AM_INIT_AUTOMAKE(libevent,2.0.10-stable) +AM_INIT_AUTOMAKE(libevent,2.0.10-stable-dev) AM_CONFIG_HEADER(config.h) -AC_DEFINE(NUMERIC_VERSION, 0x02000a00, [Numeric representation of the version]) +AC_DEFINE(NUMERIC_VERSION, 0x02000a01, [Numeric representation of the version]) dnl Initialize prefix. if test "$prefix" = "NONE"; then prefix="/usr/local" fi +AC_CANONICAL_BUILD +AC_CANONICAL_HOST +dnl the 'build' machine is where we run configure and compile +dnl the 'host' machine is where the resulting stuff runs. + +case "$host_os" in + + osf5*) + CFLAGS="$CFLAGS -D_OSF_SOURCE" + ;; +esac + +AC_USE_SYSTEM_EXTENSIONS + dnl Checks for programs. AC_PROG_CC AC_PROG_INSTALL @@ -30,6 +44,12 @@ if test "$GCC" = "yes" ; then CFLAGS="$CFLAGS -fno-strict-aliasing" fi +dnl Allow overriding defaults for some configure options using preset +dnl environment variables. + +enable_libevent_install_def=${enable_libevent_install_def-yes} +enable_libevent_regress_def=${enable_libevent_regress_def-yes} + AC_ARG_ENABLE(gcc-warnings, AS_HELP_STRING(--enable-gcc-warnings, enable verbose warnings with GCC)) AC_ARG_ENABLE(thread-support, @@ -44,15 +64,30 @@ AC_ARG_ENABLE(openssl, AC_ARG_ENABLE(debug-mode, AS_HELP_STRING(--disable-debug-mode, disable support for running in debug mode), [], [enable_debug_mode=yes]) +AC_ARG_ENABLE([libevent-install], + AS_HELP_STRING([--disable-libevent-install, disable installation of libevent]), + [], [enable_libevent_install=$enable_libevent_install_def]) +AC_ARG_ENABLE([libevent-regress], + AS_HELP_STRING([--disable-libevent-regress, skip regress in make check]), + [], [enable_libevent_regress=$enable_libevent_regress_def]) AC_PROG_LIBTOOL -dnl Uncomment "AC_DISABLE_SHARED" to make shared librraries not get +dnl Uncomment "AC_DISABLE_SHARED" to make shared libraries not get dnl built by default. You can also turn shared libs on and off from dnl the command line with --enable-shared and --disable-shared. dnl AC_DISABLE_SHARED + AC_SUBST(LIBTOOL_DEPS) +AM_CONDITIONAL([BUILD_REGRESS], [test "$enable_libevent_regress" = "yes"]) +if test "$enable_libevent_regress" = "yes" ; then + CHECK_REGRESS=regress +else + CHECK_REGRESS= +fi +AC_SUBST([CHECK_REGRESS]) + dnl Checks for libraries. AC_SEARCH_LIBS([inet_ntoa], [nsl]) AC_SEARCH_LIBS([socket], [socket]) @@ -60,6 +95,9 @@ AC_SEARCH_LIBS([inet_aton], [resolv]) AC_SEARCH_LIBS([clock_gettime], [rt]) AC_SEARCH_LIBS([sendfile], [sendfile]) +AC_CHECK_HEADERS([zlib.h]) + +if test "x$ac_cv_header_zlib_h" = "xyes"; then dnl Determine if we have zlib for regression tests dnl Don't put this one in LIBS save_LIBS="$LIBS" @@ -72,6 +110,7 @@ AC_SEARCH_LIBS([inflateEnd], [z], AC_DEFINE(HAVE_LIBZ, 1, [Define if the system has zlib])]) LIBS="$save_LIBS" AC_SUBST(ZLIB_LIBS) +fi AM_CONDITIONAL(ZLIB_REGRESS, [test "$have_zlib" = "yes"]) dnl See if we have openssl. This doesn't go in LIBS either. @@ -90,7 +129,7 @@ fi dnl Checks for header files. AC_HEADER_STDC -AC_CHECK_HEADERS(fcntl.h stdarg.h inttypes.h stdint.h stddef.h poll.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h sys/param.h sys/ioctl.h sys/select.h sys/devpoll.h port.h netinet/in.h netinet/in6.h sys/socket.h sys/uio.h arpa/inet.h sys/eventfd.h sys/mman.h sys/sendfile.h sys/wait.h netdb.h) +AC_CHECK_HEADERS([fcntl.h stdarg.h inttypes.h stdint.h stddef.h poll.h unistd.h sys/epoll.h sys/time.h sys/queue.h sys/event.h sys/param.h sys/ioctl.h sys/select.h sys/devpoll.h port.h netinet/in.h netinet/in6.h sys/socket.h sys/uio.h arpa/inet.h sys/eventfd.h sys/mman.h sys/sendfile.h sys/wait.h netdb.h]) AC_CHECK_HEADERS(sys/sysctl.h, [], [], [ #ifdef HAVE_SYS_PARAM_H #include @@ -193,32 +232,74 @@ if test x$bwin32 = xtrue; then AC_SEARCH_LIBS([getservbyname],[ws2_32]) fi +# check if we can compile with pthreads +have_pthreads=no +if test x$bwin32 != xtrue && test "$enable_thread_support" != "no"; then + OL_THREAD_CHECK([ + have_pthreads=yes + PTHREAD_LIBS="$LTHREAD_LIBS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + AC_CHECK_SIZEOF( + [pthread_t], + [], + [ + AC_INCLUDES_DEFAULT() + #include + ] + ) + ]) +fi +AC_SUBST([PTHREAD_LIBS]) +AC_SUBST([PTHREAD_CFLAGS]) +AM_CONDITIONAL([PTHREADS], [test "$have_pthreads" != "no" && test "$enable_thread_support" != "no"]) + dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST AC_C_INLINE AC_HEADER_TIME dnl Checks for library functions. -AC_CHECK_FUNCS(gettimeofday vasprintf fcntl clock_gettime strtok_r strsep getaddrinfo getnameinfo strlcpy inet_ntop inet_pton signal sigaction strtoll inet_aton pipe eventfd sendfile mmap splice arc4random arc4random_buf issetugid geteuid getegid getservbyname getprotobynumber setenv unsetenv putenv) +AC_CHECK_FUNCS([gettimeofday vasprintf fcntl clock_gettime strtok_r strsep]) +AC_CHECK_FUNCS([getnameinfo strlcpy inet_ntop inet_pton signal sigaction strtoll inet_aton pipe eventfd sendfile mmap splice arc4random arc4random_buf issetugid geteuid getegid getprotobynumber setenv unsetenv putenv]) + +AC_CACHE_CHECK( + [for getaddrinfo], + [libevent_cv_getaddrinfo], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[ + #ifdef HAVE_NETDB_H + #include + #endif + ]], + [[ + getaddrinfo; + ]] + )], + [libevent_cv_getaddrinfo=yes], + [libevent_cv_getaddrinfo=no] + )] +) +if test "$libevent_cv_getaddrinfo" = "yes" ; then + AC_DEFINE([HAVE_GETADDRINFO], [1], [Do we have getaddrinfo()?]) +else +AC_CHECK_FUNCS([getservbyname]) # Check for gethostbyname_r in all its glorious incompatible versions. # (This is cut-and-pasted from Tor, which based its logic on # Python's configure.in.) -AH_TEMPLATE(HAVE_GETHOSTBYNAME_R, - [Define this if you have any gethostbyname_r()]) - AC_CHECK_FUNC(gethostbyname_r, [ AC_MSG_CHECKING([how many arguments gethostbyname_r() wants]) OLD_CFLAGS=$CFLAGS CFLAGS="$CFLAGS $MY_CPPFLAGS $MY_THREAD_CPPFLAGS $MY_CFLAGS" - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ #include ], [[ char *cp1, *cp2; struct hostent *h1, *h2; int i1, i2; (void)gethostbyname_r(cp1,h1,cp2,i1,&h2,&i2); - ]]),[ + ]])],[ AC_DEFINE(HAVE_GETHOSTBYNAME_R) AC_DEFINE(HAVE_GETHOSTBYNAME_R_6_ARG, 1, [Define this if gethostbyname_r takes 6 arguments]) @@ -257,6 +338,10 @@ AC_CHECK_FUNC(gethostbyname_r, [ CFLAGS=$OLD_CFLAGS ]) +fi + +AH_TEMPLATE([HAVE_GETHOSTBYNAME_R], + [Define this if you have any gethostbyname_r()]) AC_CHECK_SIZEOF(long) @@ -443,7 +528,7 @@ AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(size_t) AC_CHECK_SIZEOF(void *) -AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, sa_family_t, struct addrinfo], , , +AC_CHECK_TYPES([struct in6_addr, struct sockaddr_in6, sa_family_t, struct addrinfo, struct sockaddr_storage], , , [#define _GNU_SOURCE #include #ifdef HAVE_NETINET_IN_H @@ -521,21 +606,6 @@ AC_TRY_COMPILE([], [Define to appropriate substitue if compiler doesnt have __func__]))) -# check if we can compile with pthreads -have_pthreads=no -if test x$bwin32 != xtrue && test "$enable_thread_support" != "no"; then - ACX_PTHREAD([ - AC_DEFINE(HAVE_PTHREADS, 1, - [Define if we have pthreads on this system]) - have_pthreads=yes]) - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - AC_CHECK_SIZEOF(pthread_t, , - [AC_INCLUDES_DEFAULT() - #include ] - ) -fi -AM_CONDITIONAL(PTHREADS, [test "$have_pthreads" != "no" && test "$enable_thread_support" != "no"]) - # check if we should compile locking into the library if test x$enable_thread_support = xno; then AC_DEFINE(DISABLE_THREAD_SUPPORT, 1, @@ -559,22 +629,22 @@ AM_CONDITIONAL(OPENSSL, [test "$enable_openssl" != "no" && test "$have_openssl" # Add some more warnings which we use in development but not in the # released versions. (Some relevant gcc versions can't handle these.) -if test x$enable_gcc_warnings = xyes; then +if test x$enable_gcc_warnings = xyes && test "$GCC" = "yes"; then - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([], [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [ #if !defined(__GNUC__) || (__GNUC__ < 4) #error -#endif]), have_gcc4=yes, have_gcc4=no) +#endif])], have_gcc4=yes, have_gcc4=no) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([], [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [ #if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 2) #error -#endif]), have_gcc42=yes, have_gcc42=no) +#endif])], have_gcc42=yes, have_gcc42=no) - AC_COMPILE_IFELSE(AC_LANG_PROGRAM([], [ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [ #if !defined(__GNUC__) || (__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) #error -#endif]), have_gcc45=yes, have_gcc45=no) +#endif])], have_gcc45=yes, have_gcc45=no) CFLAGS="$CFLAGS -W -Wfloat-equal -Wundef -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes -Wwrite-strings -Wredundant-decls -Wchar-subscripts -Wcomment -Wformat -Wwrite-strings -Wmissing-declarations -Wredundant-decls -Wnested-externs -Wbad-function-cast -Wswitch-enum -Werror" CFLAGS="$CFLAGS -Wno-unused-parameter -Wstrict-aliasing" @@ -599,5 +669,39 @@ if test x$enable_gcc_warnings = xyes; then fi +LIBEVENT_GC_SECTIONS= +if test "$GCC" = yes ; then + AC_CACHE_CHECK( + [if linker supports omitting unused code and data], + [libevent_cv_gc_sections_works], + [ + origCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wl,--gc-sections" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [ + if grep gc-sections conftest.err ; then + libevent_cv_gc_sections_works=no + else + libevent_cv_gc_sections_works=yes + fi + ], + [libevent_cv_gc_sections_works=no] + ) + CFLAGS="$origCFLAGS" + AS_UNSET([origCFLAGS]) + ] + ) + case "$libevent_cv_gc_sections_works" in + yes) + CFLAGS="-ffunction-sections -fdata-sections $CFLAGS" + LIBEVENT_GC_SECTIONS="-Wl,--gc-sections" + ;; + esac +fi +AC_SUBST([LIBEVENT_GC_SECTIONS]) + +AM_CONDITIONAL([INSTALL_LIBEVENT], [test "$enable_libevent_install" = "yes"]) + AC_CONFIG_FILES( [libevent.pc libevent_openssl.pc libevent_pthreads.pc] ) AC_OUTPUT(Makefile include/Makefile test/Makefile sample/Makefile) diff --git a/sntp/libevent/evdns.c b/sntp/libevent/evdns.c index a1636a14e..d085bac8a 100644 --- a/sntp/libevent/evdns.c +++ b/sntp/libevent/evdns.c @@ -3069,6 +3069,10 @@ search_request_new(struct evdns_base *base, struct evdns_request *handle, } EVUTIL_ASSERT(handle->search_origname == NULL); handle->search_origname = mm_strdup(name); + if (handle->search_origname == NULL) { + /* XXX Should we dealloc req? If yes, how? */ + return NULL; + } handle->search_state = base->global_search_state; handle->search_flags = flags; base->global_search_state->refcount++; diff --git a/sntp/libevent/evport.c b/sntp/libevent/evport.c index 4301a39c7..e77f2b299 100644 --- a/sntp/libevent/evport.c +++ b/sntp/libevent/evport.c @@ -341,6 +341,12 @@ evport_dispatch(struct event_base *base, struct timeval *tv) if (pevt->portev_events & POLLOUT) res |= EV_WRITE; + /* + * Check for the error situations or a hangup situation + */ + if (pevt->portev_events & (POLLERR|POLLHUP|POLLNVAL)) + res |= EV_READ|EV_WRITE; + EVUTIL_ASSERT(epdp->ed_nevents > fd); fdi = &(epdp->ed_fds[fd]); diff --git a/sntp/libevent/evthread_pthread.c b/sntp/libevent/evthread_pthread.c index 55495a6ca..07c02a55e 100644 --- a/sntp/libevent/evthread_pthread.c +++ b/sntp/libevent/evthread_pthread.c @@ -37,6 +37,18 @@ struct event_base; #include "mm-internal.h" #include "evthread-internal.h" +#if _EVENT_HAVE_PTHREADS < 5 /* HP-UX 10.20 has 4, needs this */ +# define pthread_mutex_init(m, a) \ + pthread_mutex_init(m, (a) \ + ? *(const pthread_mutexattr_t *)(a) \ + : pthread_mutexattr_default) +# define pthread_cond_init_def(c) pthread_cond_init((c), pthread_condattr_default) +# define PTHREAD_MUTEX_RECURSIVE MUTEX_RECURSIVE_NP +# define pthread_mutexattr_settype pthread_mutexattr_setkind_np +#else +# define pthread_cond_init_def(c) pthread_cond_init((c), NULL) +#endif + static pthread_mutexattr_t attr_recursive; static void * @@ -104,7 +116,7 @@ evthread_posix_cond_alloc(unsigned condflags) pthread_cond_t *cond = mm_malloc(sizeof(pthread_cond_t)); if (!cond) return NULL; - if (pthread_cond_init(cond, NULL)) { + if (pthread_cond_init_def(cond)) { mm_free(cond); return NULL; } diff --git a/sntp/libevent/evutil.c b/sntp/libevent/evutil.c index b769acc2b..926ebc470 100644 --- a/sntp/libevent/evutil.c +++ b/sntp/libevent/evutil.c @@ -351,6 +351,8 @@ evutil_strtoll(const char *s, char **endptr, int base) r = (ev_int64_t) _atoi64(s); while (isspace(*s)) ++s; + if (*s == '-') + ++s; while (isdigit(*s)) ++s; if (endptr) @@ -358,6 +360,36 @@ evutil_strtoll(const char *s, char **endptr, int base) return r; #elif defined(WIN32) return (ev_int64_t) _strtoi64(s, endptr, base); +#elif defined(_EVENT_SIZEOF_LONG_LONG) && _EVENT_SIZEOF_LONG_LONG == 8 + long long r; + int n; + if (base != 10 && base != 16) + return 0; + if (base == 10) { + n = sscanf(s, "%lld", &r); + } else { + unsigned long long ru=0; + n = sscanf(s, "%llx", &ru); + if (ru > EV_INT64_MAX) + return 0; + r = (long long) ru; + } + if (n != 1) + return 0; + while (EVUTIL_ISSPACE(*s)) + ++s; + if (*s == '-') + ++s; + if (base == 10) { + while (EVUTIL_ISDIGIT(*s)) + ++s; + } else { + while (EVUTIL_ISXDIGIT(*s)) + ++s; + } + if (endptr) + *endptr = (char*) s; + return r; #else #error "I don't know how to parse 64-bit integers." #endif @@ -721,6 +753,10 @@ evutil_getaddrinfo_infer_protocols(struct evutil_addrinfo *hints) } } +#if AF_UNSPEC != PF_UNSPEC +#error "I cannot build on a system where AF_UNSPEC != PF_UNSPEC" +#endif + /** Implements the part of looking up hosts by name that's common to both * the blocking and nonblocking resolver: * - Adjust 'hints' to have a reasonable socktype and protocol. @@ -771,7 +807,7 @@ evutil_getaddrinfo_common(const char *nodename, const char *servname, memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_port = htons(port); - if (hints->ai_flags & AI_PASSIVE) { + if (hints->ai_flags & EVUTIL_AI_PASSIVE) { /* Bind to :: */ } else { /* connect to ::1 */ @@ -788,7 +824,7 @@ evutil_getaddrinfo_common(const char *nodename, const char *servname, memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons(port); - if (hints->ai_flags & AI_PASSIVE) { + if (hints->ai_flags & EVUTIL_AI_PASSIVE) { /* Bind to 0.0.0.0 */ } else { /* connect to 127.0.0.1 */ @@ -958,8 +994,13 @@ addrinfo_from_hostent(const struct hostent *ent, res = evutil_addrinfo_append(res, ai); } - if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) + if (res && ((hints->ai_flags & EVUTIL_AI_CANONNAME) && ent->h_name)) { res->ai_canonname = mm_strdup(ent->h_name); + if (res->ai_canonname == NULL) { + evutil_freeaddrinfo(res); + return NULL; + } + } return res; } diff --git a/sntp/libevent/http.c b/sntp/libevent/http.c index f8de3b37f..3b0084848 100644 --- a/sntp/libevent/http.c +++ b/sntp/libevent/http.c @@ -55,6 +55,9 @@ #ifdef _EVENT_HAVE_NETINET_IN_H #include +# ifdef _XOPEN_SOURCE_EXTENDED +# include +# endif #endif #ifdef _EVENT_HAVE_NETDB_H #include @@ -1110,7 +1113,7 @@ evhttp_connection_set_local_address(struct evhttp_connection *evcon, if (evcon->bind_address) mm_free(evcon->bind_address); if ((evcon->bind_address = mm_strdup(address)) == NULL) - event_err(1, "%s: strdup", __func__); + event_warn("%s: strdup", __func__); } void @@ -2491,6 +2494,10 @@ evhttp_response_code(struct evhttp_request *req, int code, const char *reason) if (reason == NULL) reason = evhttp_response_phrase_internal(code); req->response_code_line = mm_strdup(reason); + if (req->response_code_line == NULL) { + event_warn("%s: strdup", __func__); + /* XXX what else can we do? */ + } } void @@ -3280,6 +3287,11 @@ evhttp_set_cb(struct evhttp *http, const char *uri, } http_cb->what = mm_strdup(uri); + if (http_cb->what == NULL) { + event_warn("%s: strdup", __func__); + mm_free(http_cb); + return (-3); + } http_cb->cb = cb; http_cb->cbarg = cbarg; @@ -3911,6 +3923,10 @@ parse_authority(struct evhttp_uri *uri, char *s, char *eos) EVUTIL_ASSERT(eos); if (eos == s) { uri->host = mm_strdup(""); + if (uri->host == NULL) { + event_warn("%s: strdup", __func__); + return -1; + } return 0; } @@ -3922,6 +3938,10 @@ parse_authority(struct evhttp_uri *uri, char *s, char *eos) return -1; *cp++ = '\0'; uri->userinfo = mm_strdup(s); + if (uri->userinfo == NULL) { + event_warn("%s: strdup", __func__); + return -1; + } } else { cp = s; } @@ -3949,6 +3969,10 @@ parse_authority(struct evhttp_uri *uri, char *s, char *eos) return -1; } uri->host = mm_malloc(eos-cp+1); + if (uri->host == NULL) { + event_warn("%s: malloc", __func__); + return -1; + } memcpy(uri->host, cp, eos-cp); uri->host[eos-cp] = '\0'; return 0; @@ -4011,14 +4035,14 @@ evhttp_uri_parse(const char *source_uri) struct evhttp_uri *uri = mm_calloc(1, sizeof(struct evhttp_uri)); if (uri == NULL) { - event_err(1, "%s: calloc", __func__); + event_warn("%s: calloc", __func__); goto err; } uri->port = -1; readbuf = mm_strdup(source_uri); if (readbuf == NULL) { - event_err(1, "%s: strdup", __func__); + event_warn("%s: strdup", __func__); goto err; } @@ -4039,7 +4063,10 @@ evhttp_uri_parse(const char *source_uri) if (token && scheme_ok(readp,token)) { *token = '\0'; uri->scheme = mm_strdup(readp); - + if (uri->scheme == NULL) { + event_warn("%s: strdup", __func__); + goto err; + } readp = token+1; /* eat : */ } @@ -4096,11 +4123,25 @@ evhttp_uri_parse(const char *source_uri) EVUTIL_ASSERT(path); uri->path = mm_strdup(path); + if (uri->path == NULL) { + event_warn("%s: strdup", __func__); + goto err; + } - if (query) + if (query) { uri->query = mm_strdup(query); - if (fragment) + if (uri->query == NULL) { + event_warn("%s: strdup", __func__); + goto err; + } + } + if (fragment) { uri->fragment = mm_strdup(fragment); + if (uri->fragment == NULL) { + event_warn("%s: strdup", __func__); + goto err; + } + } mm_free(readbuf); diff --git a/sntp/libevent/ipv6-internal.h b/sntp/libevent/ipv6-internal.h index 7d6fb7361..1f272a0d0 100644 --- a/sntp/libevent/ipv6-internal.h +++ b/sntp/libevent/ipv6-internal.h @@ -59,12 +59,21 @@ typedef int sa_family_t; #ifndef _EVENT_HAVE_STRUCT_SOCKADDR_IN6 struct sockaddr_in6 { + /* This will fail if we find a struct sockaddr that doesn't have + * sa_family as the first element. */ sa_family_t sin6_family; ev_uint16_t sin6_port; struct in6_addr sin6_addr; }; #endif +#ifndef AF_INET6 +#define AF_INET6 3333 +#endif +#ifndef PF_INET6 +#define PF_INET6 AF_INET6 +#endif + #ifdef __cplusplus } #endif diff --git a/sntp/libevent/m4/LICENSE-OPENLDAP b/sntp/libevent/m4/LICENSE-OPENLDAP new file mode 100644 index 000000000..05ad7571e --- /dev/null +++ b/sntp/libevent/m4/LICENSE-OPENLDAP @@ -0,0 +1,47 @@ +The OpenLDAP Public License + Version 2.8, 17 August 2003 + +Redistribution and use of this software and associated documentation +("Software"), with or without modification, are permitted provided +that the following conditions are met: + +1. Redistributions in source form must retain copyright statements + and notices, + +2. Redistributions in binary form must reproduce applicable copyright + statements and notices, this list of conditions, and the following + disclaimer in the documentation and/or other materials provided + with the distribution, and + +3. Redistributions must contain a verbatim copy of this document. + +The OpenLDAP Foundation may revise this license from time to time. +Each revision is distinguished by a version number. You may use +this Software under terms of this license revision or under the +terms of any subsequent revision of the license. + +THIS SOFTWARE IS PROVIDED BY THE OPENLDAP FOUNDATION AND ITS +CONTRIBUTORS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT +SHALL THE OPENLDAP FOUNDATION, ITS CONTRIBUTORS, OR THE AUTHOR(S) +OR OWNER(S) OF THE SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +The names of the authors and copyright holders must not be used in +advertising or otherwise to promote the sale, use or other dealing +in this Software without specific, written prior permission. Title +to copyright in this Software shall at all times remain with copyright +holders. + +OpenLDAP is a registered trademark of the OpenLDAP Foundation. + +Copyright 1999-2003 The OpenLDAP Foundation, Redwood City, +California, USA. All Rights Reserved. Permission to copy and +distribute verbatim copies of this document is granted. diff --git a/sntp/libevent/m4/acx_pthread.m4 b/sntp/libevent/m4/acx_pthread.m4 deleted file mode 100644 index d2b116945..000000000 --- a/sntp/libevent/m4/acx_pthread.m4 +++ /dev/null @@ -1,279 +0,0 @@ -##### http://autoconf-archive.cryp.to/acx_pthread.html -# -# SYNOPSIS -# -# ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) -# -# DESCRIPTION -# -# This macro figures out how to build C programs using POSIX threads. -# It sets the PTHREAD_LIBS output variable to the threads library and -# linker flags, and the PTHREAD_CFLAGS output variable to any special -# C compiler flags that are needed. (The user can also force certain -# compiler flags/libs to be tested by setting these environment -# variables.) -# -# Also sets PTHREAD_CC to any special C compiler that is needed for -# multi-threaded programs (defaults to the value of CC otherwise). -# (This is necessary on AIX to use the special cc_r compiler alias.) -# -# NOTE: You are assumed to not only compile your program with these -# flags, but also link it with them as well. e.g. you should link -# with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS -# $LIBS -# -# If you are only building threads programs, you may wish to use -# these variables in your default LIBS, CFLAGS, and CC: -# -# LIBS="$PTHREAD_LIBS $LIBS" -# CFLAGS="$CFLAGS $PTHREAD_CFLAGS" -# CC="$PTHREAD_CC" -# -# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute -# constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to -# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX). -# -# ACTION-IF-FOUND is a list of shell commands to run if a threads -# library is found, and ACTION-IF-NOT-FOUND is a list of commands to -# run it if it is not found. If ACTION-IF-FOUND is not specified, the -# default action will define HAVE_PTHREAD. -# -# Please let the authors know if this macro fails on any platform, or -# if you have any other suggestions or comments. This macro was based -# on work by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) -# (with help from M. Frigo), as well as ac_pthread and hb_pthread -# macros posted by Alejandro Forero Cuervo to the autoconf macro -# repository. We are also grateful for the helpful feedback of -# numerous users. -# -# LAST MODIFICATION -# -# 2007-07-29 -# -# COPYLEFT -# -# Copyright (c) 2007 Steven G. Johnson -# -# This program is free software: you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see -# . -# -# As a special exception, the respective Autoconf Macro's copyright -# owner gives unlimited permission to copy, distribute and modify the -# configure scripts that are the output of Autoconf when processing -# the Macro. You need not follow the terms of the GNU General Public -# License when using or distributing such scripts, even though -# portions of the text of the Macro appear in them. The GNU General -# Public License (GPL) does govern all other use of the material that -# constitutes the Autoconf Macro. -# -# This special exception to the GPL applies to versions of the -# Autoconf Macro released by the Autoconf Macro Archive. When you -# make and distribute a modified version of the Autoconf Macro, you -# may extend this special exception to the GPL to apply to your -# modified version as well. - -AC_DEFUN([ACX_PTHREAD], [ -AC_REQUIRE([AC_CANONICAL_HOST]) -AC_LANG_SAVE -AC_LANG_C -acx_pthread_ok=no - -# We used to check for pthread.h first, but this fails if pthread.h -# requires special compiler flags (e.g. on True64 or Sequent). -# It gets checked for in the link test anyway. - -# First of all, check if the user has set any of the PTHREAD_LIBS, -# etcetera environment variables, and if threads linking works using -# them: -if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS]) - AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes) - AC_MSG_RESULT($acx_pthread_ok) - if test x"$acx_pthread_ok" = xno; then - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" - fi - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" -fi - -# We must check for the threads library under a number of different -# names; the ordering is very important because some systems -# (e.g. DEC) have both -lpthread and -lpthreads, where one of the -# libraries is broken (non-POSIX). - -# Create a list of thread flags to try. Items starting with a "-" are -# C compiler flags, and other items are library names, except for "none" -# which indicates that we try without any flags at all, and "pthread-config" -# which is a program returning the flags for the Pth emulation library. - -acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config" - -# The ordering *is* (sometimes) important. Some notes on the -# individual items follow: - -# pthreads: AIX (must check this before -lpthread) -# none: in case threads are in libc; should be tried before -Kthread and -# other compiler flags to prevent continual compiler warnings -# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h) -# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able) -# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread) -# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads) -# -pthreads: Solaris/gcc -# -mthreads: Mingw32/gcc, Lynx/gcc -# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it -# doesn't hurt to check since this sometimes defines pthreads too; -# also defines -D_REENTRANT) -# ... -mt is also the pthreads flag for HP/aCC -# pthread: Linux, etcetera -# --thread-safe: KAI C++ -# pthread-config: use pthread-config program (for GNU Pth library) - -case "${host_cpu}-${host_os}" in - *solaris*) - - # On Solaris (at least, for some versions), libc contains stubbed - # (non-functional) versions of the pthreads routines, so link-based - # tests will erroneously succeed. (We need to link with -pthreads/-mt/ - # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather - # a function called by this macro, so we could check for that, but - # who knows whether they'll stub that too in a future libc.) So, - # we'll just look for -pthreads and -lpthread first: - - acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags" - ;; -esac - -if test x"$acx_pthread_ok" = xno; then -for flag in $acx_pthread_flags; do - - case $flag in - none) - AC_MSG_CHECKING([whether pthreads work without any flags]) - ;; - - -*) - AC_MSG_CHECKING([whether pthreads work with $flag]) - PTHREAD_CFLAGS="$flag" - ;; - - pthread-config) - AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no) - if test x"$acx_pthread_config" = xno; then continue; fi - PTHREAD_CFLAGS="`pthread-config --cflags`" - PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`" - ;; - - *) - AC_MSG_CHECKING([for the pthreads library -l$flag]) - PTHREAD_LIBS="-l$flag" - ;; - esac - - save_LIBS="$LIBS" - save_CFLAGS="$CFLAGS" - LIBS="$PTHREAD_LIBS $LIBS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Check for various functions. We must include pthread.h, - # since some functions may be macros. (On the Sequent, we - # need a special flag -Kthread to make this header compile.) - # We check for pthread_join because it is in -lpthread on IRIX - # while pthread_create is in libc. We check for pthread_attr_init - # due to DEC craziness with -lpthreads. We check for - # pthread_cleanup_push because it is one of the few pthread - # functions on Solaris that doesn't have a non-functional libc stub. - # We try pthread_create on general principles. - AC_TRY_LINK([#include ], - [pthread_t th; pthread_join(th, 0); - pthread_attr_init(0); pthread_cleanup_push(0, 0); - pthread_create(0,0,0,0); pthread_cleanup_pop(0); ], - [acx_pthread_ok=yes]) - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - AC_MSG_RESULT($acx_pthread_ok) - if test "x$acx_pthread_ok" = xyes; then - break; - fi - - PTHREAD_LIBS="" - PTHREAD_CFLAGS="" -done -fi - -# Various other checks: -if test "x$acx_pthread_ok" = xyes; then - save_LIBS="$LIBS" - LIBS="$PTHREAD_LIBS $LIBS" - save_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS $PTHREAD_CFLAGS" - - # Detect AIX lossage: JOINABLE attribute is called UNDETACHED. - AC_MSG_CHECKING([for joinable pthread attribute]) - attr_name=unknown - for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do - AC_TRY_LINK([#include ], [int attr=$attr; return attr;], - [attr_name=$attr; break]) - done - AC_MSG_RESULT($attr_name) - if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then - AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name, - [Define to necessary symbol if this constant - uses a non-standard name on your system.]) - fi - - AC_MSG_CHECKING([if more special flags are required for pthreads]) - flag=no - case "${host_cpu}-${host_os}" in - *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";; - *solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";; - esac - AC_MSG_RESULT(${flag}) - if test "x$flag" != xno; then - PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS" - fi - - LIBS="$save_LIBS" - CFLAGS="$save_CFLAGS" - - # More AIX lossage: must compile with xlc_r or cc_r - if test x"$GCC" != xyes; then - AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC}) - else - PTHREAD_CC=$CC - fi -else - PTHREAD_CC="$CC" -fi - -AC_SUBST(PTHREAD_LIBS) -AC_SUBST(PTHREAD_CFLAGS) -AC_SUBST(PTHREAD_CC) - -# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: -if test x"$acx_pthread_ok" = xyes; then - ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) - : -else - acx_pthread_ok=no - $2 -fi -AC_LANG_RESTORE -])dnl ACX_PTHREAD diff --git a/sntp/libevent/m4/openldap-thread-check.m4 b/sntp/libevent/m4/openldap-thread-check.m4 new file mode 100644 index 000000000..2b3191906 --- /dev/null +++ b/sntp/libevent/m4/openldap-thread-check.m4 @@ -0,0 +1,681 @@ +dnl OpenLDAP Autoconf thread check +dnl +dnl This work is part of OpenLDAP Software . +dnl +dnl Copyright 1998-2010 The OpenLDAP Foundation. +dnl All rights reserved. +dnl +dnl Redistribution and use in source and binary forms, with or without +dnl modification, are permitted only as authorized by the OpenLDAP +dnl Public License. +dnl +dnl A copy of this license is available in the file LICENSE-OPENLDAP in +dnl this directory of the distribution or, alternatively, at +dnl . +dnl +dnl -------------------------------------------------------------------- + +# OL_THREAD_CHECK([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]) + +AC_DEFUN([OL_THREAD_CHECK], [ +AC_REQUIRE([AC_CANONICAL_HOST]) +AC_LANG_SAVE +AC_LANG([C]) +OL_ARG_WITH(threads,[ --with-threads with threads], + auto, [auto nt posix mach pth lwp yes no manual] ) + +case "$ol_with_threads$host" in + auto*-*-solaris2.[[0-6]]) + dnl signals sometimes delivered to wrong thread with Solaris 2.6 + ol_with_threads=no + ;; +esac + +dnl AIX Thread requires we use cc_r or xlc_r. +dnl But only do this IF AIX and CC is not set +dnl and threads are auto|yes|posix. +dnl +dnl If we find cc_r|xlc_r, force pthreads and assume +dnl pthread_create is in $LIBS (ie: don't bring in +dnl any additional thread libraries) +dnl If we do not find cc_r|xlc_r, disable threads + +ol_aix_threads=no +case "$host" in +*-*-aix*) dnl all AIX is not a good idea. + if test -z "$CC" ; then + case "$ol_with_threads" in + auto | yes | posix) ol_aix_threads=yes ;; + esac + fi +;; +esac + +if test $ol_aix_threads = yes ; then + if test -z "${CC}" ; then + AC_CHECK_PROGS(CC,cc_r xlc_r cc) + + if test "$CC" = cc ; then + dnl no CC! don't allow --with-threads + if test $ol_with_threads != auto ; then + AC_MSG_ERROR([--with-threads requires cc_r (or other suitable compiler) on AIX]) + else + AC_MSG_WARN([disabling threads, no cc_r on AIX]) + fi + ol_with_threads=no + fi + fi + + case ${CC} in cc_r | xlc_r) + ol_with_threads=posix + ol_cv_pthread_create=yes + ;; + esac +fi + +dnl ---------------------------------------------------------------- +dnl Threads? +ol_link_threads=no +ol_with_yielding_select=${ol_with_yielding_select-auto} + +case $ol_with_threads in auto | yes | nt) + + OL_NT_THREADS + + if test "$ol_cv_nt_threads" = yes ; then + ol_link_threads=nt + ol_with_threads=found + ol_with_yielding_select=yes + + AC_DEFINE([HAVE_NT_SERVICE_MANAGER], [1], [if you have NT Service Manager]) + AC_DEFINE([HAVE_NT_EVENT_LOG], [1], [if you have NT Event Log]) + fi + + if test $ol_with_threads = nt ; then + AC_MSG_ERROR([could not locate NT Threads]) + fi + ;; +esac + +case $ol_with_threads in auto | yes | posix) + + AC_CHECK_HEADERS(pthread.h) + + if test $ac_cv_header_pthread_h = yes ; then + OL_POSIX_THREAD_VERSION + + if test $ol_cv_pthread_version != 0 ; then + AC_DEFINE_UNQUOTED([HAVE_PTHREADS], [$ol_cv_pthread_version], + [define to pthreads API spec revision]) + else + AC_MSG_ERROR([unknown pthread version]) + fi + + # consider threads found + ol_with_threads=found + + OL_HEADER_LINUX_THREADS + OL_HEADER_GNU_PTH_PTHREAD_H + + if test $ol_cv_header_gnu_pth_pthread_h = no ; then + AC_CHECK_HEADERS(sched.h) + fi + + dnl Now the hard part, how to link? + dnl + dnl currently supported checks: + dnl + dnl Check for no flags + dnl pthread_create() in $LIBS + dnl + dnl Check special pthread (final) flags + dnl [skipped] pthread_create() with -mt (Solaris) [disabled] + dnl pthread_create() with -kthread (FreeBSD) + dnl pthread_create() with -pthread (FreeBSD/Digital Unix) + dnl pthread_create() with -pthreads (?) + dnl pthread_create() with -mthreads (AIX) + dnl pthread_create() with -thread (?) + dnl + dnl Check pthread (final) libraries + dnl pthread_mutex_unlock() in -lpthread -lmach -lexc -lc_r (OSF/1) + dnl pthread_mutex_lock() in -lpthread -lmach -lexc (OSF/1) + dnl [skipped] pthread_mutex_trylock() in -lpthread -lexc (OSF/1) + dnl pthread_join() -Wl,-woff,85 -lpthread (IRIX) + dnl pthread_create() in -lpthread (many) + dnl pthread_create() in -lc_r (FreeBSD) + dnl + dnl Check pthread (draft4) flags (depreciated) + dnl pthread_create() with -threads (OSF/1) + dnl + dnl Check pthread (draft4) libraries (depreciated) + dnl pthread_mutex_unlock() in -lpthreads -lmach -lexc -lc_r (OSF/1) + dnl pthread_mutex_lock() in -lpthreads -lmach -lexc (OSF/1) + dnl pthread_mutex_trylock() in -lpthreads -lexc (OSF/1) + dnl pthread_create() in -lpthreads (many) + dnl + + dnl pthread_create in $LIBS + AC_CACHE_CHECK([for pthread_create in default libraries], + ol_cv_pthread_create,[ + AC_RUN_IFELSE([OL_PTHREAD_TEST_PROGRAM], + [ol_cv_pthread_create=yes], + [ol_cv_pthread_create=no], + [AC_TRY_LINK(OL_PTHREAD_TEST_INCLUDES,OL_PTHREAD_TEST_FUNCTION, + [ol_cv_pthread_create=yes], + [ol_cv_pthread_create=no])])]) + + if test $ol_cv_pthread_create != no ; then + ol_link_threads=posix + ol_link_pthreads="" + fi + +dnl OL_PTHREAD_TRY([-mt], [ol_cv_pthread_mt]) + OL_PTHREAD_TRY([-kthread], [ol_cv_pthread_kthread]) + OL_PTHREAD_TRY([-pthread], [ol_cv_pthread_pthread]) + OL_PTHREAD_TRY([-pthreads], [ol_cv_pthread_pthreads]) + OL_PTHREAD_TRY([-mthreads], [ol_cv_pthread_mthreads]) + OL_PTHREAD_TRY([-thread], [ol_cv_pthread_thread]) + + OL_PTHREAD_TRY([-lpthread -lmach -lexc -lc_r], + [ol_cv_pthread_lpthread_lmach_lexc_lc_r]) + OL_PTHREAD_TRY([-lpthread -lmach -lexc], + [ol_cv_pthread_lpthread_lmach_lexc]) +dnl OL_PTHREAD_TRY([-lpthread -lexc], +dnl [ol_cv_pthread_lpthread_lexc]) + + OL_PTHREAD_TRY([-lpthread -Wl,-woff,85], + [ol_cv_pthread_lib_lpthread_woff]) + + OL_PTHREAD_TRY([-lpthread], [ol_cv_pthread_lpthread]) + OL_PTHREAD_TRY([-lc_r], [ol_cv_pthread_lc_r]) + + OL_PTHREAD_TRY([-threads], [ol_cv_pthread_threads]) + + OL_PTHREAD_TRY([-lpthreads -lmach -lexc -lc_r], + [ol_cv_pthread_lpthreads_lmach_lexc_lc_r]) + OL_PTHREAD_TRY([-lpthreads -lmach -lexc], + [ol_cv_pthread_lpthreads_lmach_lexc]) + OL_PTHREAD_TRY([-lpthreads -lexc], + [ol_cv_pthread_lpthreads_lexc]) + + OL_PTHREAD_TRY([-lpthreads],[ol_cv_pthread_lib_lpthreads]) + + if test $ol_link_threads != no ; then + LTHREAD_LIBS="$LTHREAD_LIBS $ol_link_pthreads" + + dnl save flags + save_CPPFLAGS="$CPPFLAGS" + save_LIBS="$LIBS" + LIBS="$LTHREAD_LIBS $LIBS" + + dnl All POSIX Thread (final) implementations should have + dnl sched_yield instead of pthread yield. + dnl check for both, and thr_yield for Solaris + AC_CHECK_FUNCS(sched_yield pthread_yield thr_yield) + + if test $ac_cv_func_sched_yield = no && + test $ac_cv_func_pthread_yield = no && + test $ac_cv_func_thr_yield = no ; then + dnl Digital UNIX has sched_yield() in -lrt + AC_CHECK_LIB(rt, sched_yield, + [LTHREAD_LIBS="$LTHREAD_LIBS -lrt" + AC_DEFINE([HAVE_SCHED_YIELD], [1], + [Define if you have the sched_yield function.]) + ac_cv_func_sched_yield=yes], + [ac_cv_func_sched_yield=no]) + fi + if test $ac_cv_func_sched_yield = no && + test $ac_cv_func_pthread_yield = no && + test "$ac_cv_func_thr_yield" = no ; then + AC_MSG_WARN([could not locate sched_yield() or pthread_yield()]) + fi + + dnl Check functions for compatibility + AC_CHECK_FUNCS(pthread_kill) + + dnl Check for pthread_rwlock_destroy with + dnl as pthread_rwlock_t may not be defined. + AC_CACHE_CHECK([for pthread_rwlock_destroy with ], + [ol_cv_func_pthread_rwlock_destroy], [ + dnl save the flags + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +pthread_rwlock_t rwlock; +]], [[pthread_rwlock_destroy(&rwlock);]])],[ol_cv_func_pthread_rwlock_destroy=yes],[ol_cv_func_pthread_rwlock_destroy=no]) + ]) + if test $ol_cv_func_pthread_rwlock_destroy = yes ; then + AC_DEFINE([HAVE_PTHREAD_RWLOCK_DESTROY], [1], + [define if you have pthread_rwlock_destroy function]) + fi + + dnl Check for pthread_detach with inclusion + dnl as it's symbol may have been mangled. + AC_CACHE_CHECK([for pthread_detach with ], + [ol_cv_func_pthread_detach], [ + dnl save the flags + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +#ifndef NULL +#define NULL (void*)0 +#endif +]], [[pthread_detach(NULL);]])],[ol_cv_func_pthread_detach=yes],[ol_cv_func_pthread_detach=no]) + ]) + + if test $ol_cv_func_pthread_detach = no ; then + AC_MSG_ERROR([could not locate pthread_detach()]) + fi + + AC_DEFINE([HAVE_PTHREAD_DETACH], [1], + [define if you have pthread_detach function]) + + dnl Check for setconcurreny functions + AC_CHECK_FUNCS( \ + pthread_setconcurrency \ + pthread_getconcurrency \ + thr_setconcurrency \ + thr_getconcurrency \ + ) + + OL_SYS_LINUX_THREADS + OL_LINUX_THREADS + + if test $ol_cv_linux_threads = error; then + AC_MSG_ERROR([LinuxThreads header/library mismatch]); + fi + + AC_CACHE_CHECK([if pthread_create() works], + ol_cv_pthread_create_works,[ + AC_RUN_IFELSE([OL_PTHREAD_TEST_PROGRAM], + [ol_cv_pthread_create_works=yes], + [ol_cv_pthread_create_works=no], + [dnl assume yes + ol_cv_pthread_create_works=yes])]) + + if test $ol_cv_pthread_create_works = no ; then + AC_MSG_ERROR([pthread_create is not usable, check environment settings]) + fi + + ol_replace_broken_yield=no +dnl case "$host" in +dnl *-*-linux*) +dnl AC_CHECK_FUNCS(nanosleep) +dnl ol_replace_broken_yield=yes +dnl ;; +dnl esac + + if test $ol_replace_broken_yield = yes ; then + AC_DEFINE([REPLACE_BROKEN_YIELD], [1], + [define if sched_yield yields the entire process]) + fi + + dnl Check if select causes an yield + if test x$ol_with_yielding_select = xauto ; then + AC_CACHE_CHECK([if select yields when using pthreads], + ol_cv_pthread_select_yields,[ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +#include +#include +#ifndef NULL +#define NULL (void*) 0 +#endif + +static int fildes[2]; + +static void *task(p) + void *p; +{ + int i; + struct timeval tv; + + fd_set rfds; + + tv.tv_sec=10; + tv.tv_usec=0; + + FD_ZERO(&rfds); + FD_SET(fildes[0], &rfds); + + /* we're not interested in any fds */ + i = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + + if(i < 0) { + perror("select"); + exit(10); + } + + exit(0); /* if we exit here, the select blocked the whole process */ +} + +int main(argc, argv) + int argc; + char **argv; +{ + pthread_t t; + + /* create a pipe to select */ + if(pipe(&fildes[0])) { + perror("select"); + exit(1); + } + +#ifdef HAVE_PTHREAD_SETCONCURRENCY + (void) pthread_setconcurrency(2); +#else +#ifdef HAVE_THR_SETCONCURRENCY + /* Set Solaris LWP concurrency to 2 */ + thr_setconcurrency(2); +#endif +#endif + +#if HAVE_PTHREADS < 6 + pthread_create(&t, pthread_attr_default, task, NULL); +#else + pthread_create(&t, NULL, task, NULL); +#endif + + /* make sure task runs first */ +#ifdef HAVE_THR_YIELD + thr_yield(); +#elif defined( HAVE_SCHED_YIELD ) + sched_yield(); +#elif defined( HAVE_PTHREAD_YIELD ) + pthread_yield(); +#endif + + exit(2); +}]])],[ol_cv_pthread_select_yields=no],[ol_cv_pthread_select_yields=yes],[ol_cv_pthread_select_yields=cross])]) + + if test $ol_cv_pthread_select_yields = cross ; then + AC_MSG_ERROR([crossing compiling: use --with-yielding_select=yes|no|manual]) + fi + + if test $ol_cv_pthread_select_yields = yes ; then + ol_with_yielding_select=yes + fi + fi + + dnl restore flags + CPPFLAGS="$save_CPPFLAGS" + LIBS="$save_LIBS" + else + AC_MSG_ERROR([could not locate usable POSIX Threads]) + fi + fi + + if test $ol_with_threads = posix ; then + AC_MSG_ERROR([could not locate POSIX Threads]) + fi + ;; +esac + +case $ol_with_threads in auto | yes | mach) + + dnl check for Mach CThreads + AC_CHECK_HEADERS(mach/cthreads.h cthreads.h) + if test $ac_cv_header_mach_cthreads_h = yes ; then + ol_with_threads=found + + dnl check for cthreads support in current $LIBS + AC_CHECK_FUNC(cthread_fork,[ol_link_threads=yes]) + + if test $ol_link_threads = no ; then + dnl try -all_load + dnl this test needs work + AC_CACHE_CHECK([for cthread_fork with -all_load], + [ol_cv_cthread_all_load], [ + dnl save the flags + save_LIBS="$LIBS" + LIBS="-all_load $LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ + cthread_fork((void *)0, (void *)0); + ]])],[ol_cv_cthread_all_load=yes],[ol_cv_cthread_all_load=no]) + dnl restore the LIBS + LIBS="$save_LIBS" + ]) + + if test $ol_cv_cthread_all_load = yes ; then + LTHREAD_LIBS="$LTHREAD_LIBS -all_load" + ol_link_threads=mach + ol_with_threads=found + fi + fi + + elif test $ac_cv_header_cthreads_h = yes ; then + dnl Hurd variant of Mach Cthreads + dnl uses and -lthreads + + ol_with_threads=found + + dnl save the flags + save_LIBS="$LIBS" + LIBS="$LIBS -lthreads" + AC_CHECK_FUNC(cthread_fork,[ol_link_threads=yes]) + LIBS="$save_LIBS" + + if test $ol_link_threads = yes ; then + LTHREAD_LIBS="-lthreads" + ol_link_threads=mach + ol_with_threads=found + else + AC_MSG_ERROR([could not link with Mach CThreads]) + fi + + elif test $ol_with_threads = mach ; then + AC_MSG_ERROR([could not locate Mach CThreads]) + fi + + if test $ol_link_threads = mach ; then + AC_DEFINE([HAVE_MACH_CTHREADS], [1], + [define if you have Mach Cthreads]) + elif test $ol_with_threads = found ; then + AC_MSG_ERROR([could not link with Mach CThreads]) + fi + ;; +esac + +case $ol_with_threads in auto | yes | pth) + + AC_CHECK_HEADERS(pth.h) + + if test $ac_cv_header_pth_h = yes ; then + AC_CHECK_LIB(pth, pth_version, [have_pth=yes], [have_pth=no]) + + if test $have_pth = yes ; then + AC_DEFINE([HAVE_GNU_PTH], [1], [if you have GNU Pth]) + LTHREAD_LIBS="$LTHREAD_LIBS -lpth" + ol_link_threads=pth + ol_with_threads=found + + if test x$ol_with_yielding_select = xauto ; then + ol_with_yielding_select=yes + fi + fi + fi + ;; +esac + +case $ol_with_threads in auto | yes | lwp) + + dnl check for SunOS5 LWP + AC_CHECK_HEADERS(thread.h synch.h) + if test $ac_cv_header_thread_h = yes && + test $ac_cv_header_synch_h = yes ; then + AC_CHECK_LIB(thread, thr_create, [have_thr=yes], [have_thr=no]) + + if test $have_thr = yes ; then + AC_DEFINE([HAVE_THR], [1], + [if you have Solaris LWP (thr) package]) + LTHREAD_LIBS="$LTHREAD_LIBS -lthread" + ol_link_threads=thr + + if test x$ol_with_yielding_select = xauto ; then + ol_with_yielding_select=yes + fi + + dnl Check for setconcurrency functions + AC_CHECK_FUNCS( \ + thr_setconcurrency \ + thr_getconcurrency \ + ) + fi + fi + + dnl check for SunOS4 LWP + AC_CHECK_HEADERS(lwp/lwp.h) + if test $ac_cv_header_lwp_lwp_h = yes ; then + AC_CHECK_LIB(lwp, lwp_create, [have_lwp=yes], [have_lwp=no]) + + if test $have_lwp = yes ; then + AC_DEFINE([HAVE_LWP], [1], + [if you have SunOS LWP package]) + LTHREAD_LIBS="$LTHREAD_LIBS -llwp" + ol_link_threads=lwp + + if test x$ol_with_yielding_select = xauto ; then + ol_with_yielding_select=no + fi + fi + fi + ;; +esac + +if test $ol_with_yielding_select = yes ; then + AC_DEFINE([HAVE_YIELDING_SELECT], [1], + [define if select implicitly yields]) +fi + +if test $ol_with_threads = manual ; then + dnl User thinks he can manually configure threads. + ol_link_threads=yes + + AC_MSG_WARN([thread defines and link options must be set manually]) + + AC_CHECK_HEADERS(pthread.h sched.h) + AC_CHECK_FUNCS(sched_yield pthread_yield) + OL_HEADER_LINUX_THREADS + + AC_CHECK_HEADERS(mach/cthreads.h) + AC_CHECK_HEADERS(lwp/lwp.h) + AC_CHECK_HEADERS(thread.h synch.h) +fi + +if test $ol_link_threads != no && test $ol_link_threads != nt ; then + dnl needed to get reentrant/threadsafe versions + dnl + AC_DEFINE([REENTRANT], [1], [enable thread safety]) + AC_DEFINE([_REENTRANT], [1], [enable thread safety]) + AC_DEFINE([THREAD_SAFE], [1], [enable thread safety]) + AC_DEFINE([_THREAD_SAFE], [1], [enable thread safety]) + AC_DEFINE([THREADSAFE], [1], [enable thread safety]) + AC_DEFINE([_THREADSAFE], [1], [enable thread safety]) + AC_DEFINE([_SGI_MP_SOURCE], [1], [enable thread safety]) + + dnl The errno declaration may dependent upon _REENTRANT. + dnl If it does, we must link with thread support. + AC_CACHE_CHECK([for thread specific errno], + [ol_cv_errno_thread_specific], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[errno = 0;]])],[ol_cv_errno_thread_specific=yes],[ol_cv_errno_thread_specific=no]) + ]) + + dnl The h_errno declaration may dependent upon _REENTRANT. + dnl If it does, we must link with thread support. + AC_CACHE_CHECK([for thread specific h_errno], + [ol_cv_h_errno_thread_specific], [ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[h_errno = 0;]])],[ol_cv_h_errno_thread_specific=yes],[ol_cv_h_errno_thread_specific=no]) + ]) + + if test $ol_cv_errno_thread_specific != yes || + test $ol_cv_h_errno_thread_specific != yes ; then + LIBS="$LTHREAD_LIBS $LIBS" + LTHREAD_LIBS="" + fi + +dnl When in thread environment, use +dnl #if defined( HAVE_REENTRANT_FUNCTIONS ) || defined( HAVE_FUNC_R ) +dnl func_r(...); +dnl #else +dnl # if defined( HAVE_THREADS ) +dnl /* lock */ +dnl # endif +dnl func(...); +dnl # if defined( HAVE_THREADS ) +dnl /* unlock */ +dnl # endif +dnl #endif +dnl +dnl HAVE_REENTRANT_FUNCTIONS is derived from: +dnl _POSIX_REENTRANT_FUNCTIONS +dnl _POSIX_THREAD_SAFE_FUNCTIONS +dnl _POSIX_THREADSAFE_FUNCTIONS +dnl +dnl and is currently defined in +dnl +dnl HAVE_THREADS is defined by iff -UNO_THREADS +dnl +dnl libldap/*.c should only include iff +dnl LDAP_R_COMPILE is defined. ie: +dnl #ifdef LDAP_R_COMPILE +dnl # include +dnl #endif +dnl +dnl LDAP_R_COMPILE is defined by libldap_r/Makefile.in +dnl specifically for compiling the threadsafe version of +dnl the ldap library (-lldap_r). +dnl +dnl dnl check for reentrant/threadsafe functions +dnl dnl +dnl dnl note: these should only be used when linking +dnl dnl with $LTHREAD_LIBS +dnl dnl +dnl save_CPPFLAGS="$CPPFLAGS" +dnl save_LIBS="$LIBS" +dnl LIBS="$LTHREAD_LIBS $LIBS" +dnl AC_CHECK_FUNCS( \ +dnl gmtime_r \ +dnl gethostbyaddr_r gethostbyname_r \ +dnl feof_unlocked unlocked_feof \ +dnl putc_unlocked unlocked_putc \ +dnl flockfile ftrylockfile \ +dnl ) +dnl CPPFLAGS="$save_CPPFLAGS" +dnl LIBS="$save_LIBS" +fi + +if test $ol_link_threads = no ; then + if test $ol_with_threads = yes ; then + AC_MSG_ERROR([no suitable thread support]) + fi + + if test $ol_with_threads = auto ; then + AC_MSG_WARN([no suitable thread support, disabling threads]) + ol_with_threads=no + fi + + AC_DEFINE([NO_THREADS], [1], + [define if you have (or want) no threads]) + LTHREAD_LIBS="" + BUILD_THREAD=no +else + BUILD_THREAD=yes +fi + +if test $ol_link_threads != no ; then + AC_DEFINE([LDAP_API_FEATURE_X_OPENLDAP_THREAD_SAFE], [1], + [define to 1 if library is thread safe]) +fi + +# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND: +case "$ol_with_threads" in + no) + ol_pthread_ok=no + $2 + ;; + *) + ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1]) + ;; +esac + +AC_LANG_RESTORE +]) diff --git a/sntp/libevent/m4/openldap.m4 b/sntp/libevent/m4/openldap.m4 new file mode 100644 index 000000000..49ffb8705 --- /dev/null +++ b/sntp/libevent/m4/openldap.m4 @@ -0,0 +1,1131 @@ +dnl OpenLDAP Autoconf Macros +dnl $OpenLDAP: pkg/ldap/build/openldap.m4,v 1.157.2.10 2010/04/13 20:22:21 kurt Exp $ +dnl This work is part of OpenLDAP Software . +dnl +dnl Copyright 1998-2010 The OpenLDAP Foundation. +dnl All rights reserved. +dnl +dnl Redistribution and use in source and binary forms, with or without +dnl modification, are permitted only as authorized by the OpenLDAP +dnl Public License. +dnl +dnl A copy of this license is available in the file LICENSE-OPENLDAP in +dnl this directory of the distribution or, alternatively, at +dnl . +dnl +dnl -------------------------------------------------------------------- +dnl Restricted form of AC_ARG_ENABLE that limits user options +dnl +dnl $1 = option name +dnl $2 = help-string +dnl $3 = default value (auto). "--" means do not set it by default +dnl $4 = allowed values (auto yes no) +dnl $5 = overridden default +AC_DEFUN([OL_ARG_ENABLE], [# OpenLDAP --enable-$1 + pushdef([ol_DefVal],ifelse($3,,auto,$3)) + AC_ARG_ENABLE($1,ifelse($4,,[$2],[$2] translit([$4],[ ],[|])) ifelse($3,--,,@<:@ol_DefVal@:>@),[ + ol_arg=invalid + for ol_val in ifelse($4,,[auto yes no],[$4]) ; do + if test "$enableval" = "$ol_val" ; then + ol_arg="$ol_val" + fi + done + if test "$ol_arg" = "invalid" ; then + AC_MSG_ERROR(bad value $enableval for --enable-$1) + fi + ol_enable_$1="$ol_arg" +]ifelse($3,--,,[, +[ ol_enable_$1=ifelse($5,,ol_DefVal,[${]$5[:-]ol_DefVal[}])]]))dnl +dnl AC_MSG_RESULT([OpenLDAP -enable-$1 $ol_enable_$1]) + popdef([ol_DefVal]) +# end --enable-$1 +])dnl +dnl +dnl -------------------------------------------------------------------- +dnl Restricted form of AC_ARG_WITH that limits user options +dnl +dnl $1 = option name +dnl $2 = help-string +dnl $3 = default value (no) +dnl $4 = allowed values (yes or no) +AC_DEFUN([OL_ARG_WITH], [# OpenLDAP --with-$1 + AC_ARG_WITH($1,[$2 @<:@]ifelse($3,,yes,$3)@:>@,[ + ol_arg=invalid + for ol_val in ifelse($4,,[yes no],[$4]) ; do + if test "$withval" = "$ol_val" ; then + ol_arg="$ol_val" + fi + done + if test "$ol_arg" = "invalid" ; then + AC_MSG_ERROR(bad value $withval for --with-$1) + fi + ol_with_$1="$ol_arg" +], +[ ol_with_$1=ifelse($3,,"no","$3")])dnl +dnl AC_MSG_RESULT([OpenLDAP --with-$1 $ol_with_$1]) +# end --with-$1 +])dnl +dnl ==================================================================== +dnl Check for dependency generation flag +AC_DEFUN([OL_MKDEPEND], [# test for make depend flag +OL_MKDEP= +OL_MKDEP_FLAGS= +if test -z "${MKDEP}"; then + OL_MKDEP="${CC-cc}" + if test -z "${MKDEP_FLAGS}"; then + AC_CACHE_CHECK([for ${OL_MKDEP} depend flag], ol_cv_mkdep, [ + ol_cv_mkdep=no + for flag in "-M" "-xM"; do + cat > conftest.c </dev/null 2>&1 + then + if test ! -f conftest."${ac_object}" ; then + ol_cv_mkdep=$flag + OL_MKDEP_FLAGS="$flag" + break + fi + fi + done + rm -f conftest* + ]) + test "$ol_cv_mkdep" = no && OL_MKDEP=":" + else + cc_cv_mkdep=yes + OL_MKDEP_FLAGS="${MKDEP_FLAGS}" + fi +else + cc_cv_mkdep=yes + OL_MKDEP="${MKDEP}" + OL_MKDEP_FLAGS="${MKDEP_FLAGS}" +fi +AC_SUBST(OL_MKDEP) +AC_SUBST(OL_MKDEP_FLAGS) +]) +dnl +dnl ==================================================================== +dnl Check if system uses EBCDIC instead of ASCII +AC_DEFUN([OL_CPP_EBCDIC], [# test for EBCDIC +AC_CACHE_CHECK([for EBCDIC],ol_cv_cpp_ebcdic,[ + AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ +#if !('M' == 0xd4) +#include <__ASCII__/generate_error.h> +#endif +]])],[ol_cv_cpp_ebcdic=yes],[ol_cv_cpp_ebcdic=no])]) +if test $ol_cv_cpp_ebcdic = yes ; then + AC_DEFINE(HAVE_EBCDIC,1, [define if system uses EBCDIC instead of ASCII]) +fi +]) +dnl +dnl -------------------------------------------------------------------- +dnl Check for MSVC +AC_DEFUN([OL_MSVC], +[AC_REQUIRE_CPP()dnl +AC_CACHE_CHECK([whether we are using MS Visual C++], ol_cv_msvc, +[AC_PREPROC_IFELSE([AC_LANG_SOURCE([[ +#ifndef _MSC_VER +#include <__FOO__/generate_error.h> +#endif +]])],[ol_cv_msvc=yes],[ol_cv_msvc=no])])]) + +dnl -------------------------------------------------------------------- +dnl OpenLDAP version of STDC header check w/ EBCDIC support +AC_DEFUN([OL_HEADER_STDC], +[AC_REQUIRE_CPP()dnl +AC_REQUIRE([OL_CPP_EBCDIC])dnl +AC_CACHE_CHECK([for ANSI C header files], ol_cv_header_stdc, +[AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include +#include +#include +#include ]])],[ol_cv_header_stdc=yes],[ol_cv_header_stdc=no]) + +if test $ol_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +AC_EGREP_HEADER(memchr, string.h, , ol_cv_header_stdc=no) +fi + +if test $ol_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +AC_EGREP_HEADER(free, stdlib.h, , ol_cv_header_stdc=no) +fi + +if test $ol_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +AC_RUN_IFELSE([AC_LANG_SOURCE([[#include +#ifndef HAVE_EBCDIC +# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#else +# define ISLOWER(c) (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) +# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) +#endif +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } +]])],[],[ol_cv_header_stdc=no],[:]) +fi]) +if test $ol_cv_header_stdc = yes; then + AC_DEFINE([STDC_HEADERS], [1], [is standard C provided?]) +fi +ac_cv_header_stdc=disable +]) +dnl +dnl ==================================================================== +dnl DNS resolver macros +AC_DEFUN([OL_RESOLVER_TRY], +[if test $ol_cv_lib_resolver = no ; then + AC_CACHE_CHECK([for resolver link (]ifelse($2,,default,$2)[)],[$1], +[ + ol_RESOLVER_LIB=ifelse($2,,,$2) + ol_LIBS=$LIBS + LIBS="$ol_RESOLVER_LIB $LIBS" + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#include +#ifdef HAVE_ARPA_NAMESER_H +# include +#endif +#ifdef HAVE_RESOLV_H +# include +#endif +]], [[{ + int len, status; + char *request = NULL; + unsigned char reply[64*1024]; + unsigned char host[64*1024]; + unsigned char *p; + +#ifdef NS_HFIXEDSZ + /* Bind 8/9 interface */ + len = res_query(request, ns_c_in, ns_t_srv, reply, sizeof(reply)); +#else + /* Bind 4 interface */ +# ifndef T_SRV +# define T_SRV 33 +# endif + len = res_query(request, C_IN, T_SRV, reply, sizeof(reply)); +#endif + p = reply; +#ifdef NS_HFIXEDSZ + /* Bind 8/9 interface */ + p += NS_HFIXEDSZ; +#elif defined(HFIXEDSZ) + /* Bind 4 interface w/ HFIXEDSZ */ + p += HFIXEDSZ; +#else + /* Bind 4 interface w/o HFIXEDSZ */ + p += sizeof(HEADER); +#endif + status = dn_expand( reply, reply+len, p, host, sizeof(host)); +}]])],[$1=yes],[$1=no]) + + LIBS="$ol_LIBS" +]) + + if test $$1 = yes ; then + ol_cv_lib_resolver=ifelse($2,,yes,$2) + fi +fi +]) +dnl -------------------------------------------------------------------- +dnl Try to locate appropriate library +AC_DEFUN([OL_RESOLVER_LINK], +[ol_cv_lib_resolver=no +OL_RESOLVER_TRY(ol_cv_resolver_none) +OL_RESOLVER_TRY(ol_cv_resolver_resolv,[-lresolv]) +OL_RESOLVER_TRY(ol_cv_resolver_bind,[-lbind]) +]) +dnl +dnl ==================================================================== +dnl International Components for Unicode (ICU) +AC_DEFUN([OL_ICU], +[ol_icu=no +AC_CHECK_HEADERS( unicode/utypes.h ) +if test $ac_cv_header_unicode_utypes_h = yes ; then + dnl OL_ICULIBS="-licui18n -licuuc -licudata" + OL_ICULIBS="-licuuc -licudata" + + AC_CACHE_CHECK([for ICU libraries], [ol_cv_lib_icu], [ + ol_LIBS="$LIBS" + LIBS="$OL_ICULIBS $LIBS" + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#include +]], [[ +(void) u_errorName(0); +]])],[ol_cv_lib_icu=yes],[ol_cv_lib_icu=no]) + LIBS="$ol_LIBS" +]) + + if test $ol_cv_lib_icu != no ; then + ol_icu="$OL_ICULIBS" + AC_DEFINE([HAVE_ICU], [1], [define if you actually have ICU]) + fi +fi +]) +dnl +dnl ==================================================================== +dnl Berkeley DB macros +dnl +dnl -------------------------------------------------------------------- +dnl Try to link +AC_DEFUN([OL_BERKELEY_DB_TRY], +[if test $ol_cv_lib_db = no ; then + AC_CACHE_CHECK([for Berkeley DB link (]ifelse($2,,default,$2)[)],[$1], +[ + ol_DB_LIB=ifelse($2,,,$2) + ol_LIBS=$LIBS + LIBS="$ol_DB_LIB $LTHREAD_LIBS $LIBS" + + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_DB_185_H +# include +#else +# include +#endif + +#ifndef DB_VERSION_MAJOR +# define DB_VERSION_MAJOR 1 +#endif + +#ifndef NULL +#define NULL ((void*)0) +#endif +]], [[ +#if DB_VERSION_MAJOR > 2 + db_env_create( NULL, 0 ); +#elif DB_VERSION_MAJOR > 1 + db_appexit( NULL ); +#else + (void) dbopen( NULL, 0, 0, 0, NULL); +#endif +]])],[$1=yes],[$1=no]) + + LIBS="$ol_LIBS" +]) + + if test $$1 = yes ; then + ol_cv_lib_db=ifelse($2,,yes,$2) + fi +fi +]) +dnl +dnl -------------------------------------------------------------------- +dnl Get major and minor version from +AC_DEFUN([OL_BDB_HEADER_VERSION], +[AC_CACHE_CHECK([for Berkeley DB major version in db.h], [ol_cv_bdb_major],[ + AC_LANG_CONFTEST([ +#include +#ifndef DB_VERSION_MAJOR +# define DB_VERSION_MAJOR 1 +#endif +__db_version DB_VERSION_MAJOR +]) + set X `eval "$ac_cpp conftest.$ac_ext" | $EGREP __db_version` none none + ol_cv_bdb_major=${3} +]) +case $ol_cv_bdb_major in [[1-9]]*) : ;; *) + AC_MSG_ERROR([Unknown Berkeley DB major version in db.h]) ;; +esac + +dnl Determine minor version +AC_CACHE_CHECK([for Berkeley DB minor version in db.h], [ol_cv_bdb_minor],[ + AC_LANG_CONFTEST([ +#include +#ifndef DB_VERSION_MINOR +# define DB_VERSION_MINOR 0 +#endif +__db_version DB_VERSION_MINOR +]) + set X `eval "$ac_cpp conftest.$ac_ext" | $EGREP __db_version` none none + ol_cv_bdb_minor=${3} +]) +case $ol_cv_bdb_minor in [[0-9]]*) : ;; *) + AC_MSG_ERROR([Unknown Berkeley DB minor version in db.h]) ;; +esac +]) +dnl +dnl -------------------------------------------------------------------- +dnl Try to locate appropriate library +AC_DEFUN([OL_BERKELEY_DB_LINK], +[ol_cv_lib_db=no + +if test $ol_cv_bdb_major = 4 ; then + OL_BERKELEY_DB_TRY(ol_cv_db_db_4_dot_m,[-ldb-4.$ol_cv_bdb_minor]) + OL_BERKELEY_DB_TRY(ol_cv_db_db4m,[-ldb4$ol_cv_bdb_minor]) + OL_BERKELEY_DB_TRY(ol_cv_db_db_4m,[-ldb-4$ol_cv_bdb_minor]) + OL_BERKELEY_DB_TRY(ol_cv_db_db_4_m,[-ldb-4-$ol_cv_bdb_minor]) + OL_BERKELEY_DB_TRY(ol_cv_db_db_4,[-ldb-4]) + OL_BERKELEY_DB_TRY(ol_cv_db_db4,[-ldb4]) + OL_BERKELEY_DB_TRY(ol_cv_db_db,[-ldb]) +fi +OL_BERKELEY_DB_TRY(ol_cv_db_none) +]) +dnl +dnl -------------------------------------------------------------------- +dnl Check if Berkeley DB version +AC_DEFUN([OL_BERKELEY_DB_VERSION], +[AC_CACHE_CHECK([for Berkeley DB library and header version match], [ol_cv_berkeley_db_version], [ + ol_LIBS="$LIBS" + LIBS="$LTHREAD_LIBS $LIBS" + if test $ol_cv_lib_db != yes ; then + LIBS="$ol_cv_lib_db $LIBS" + fi + + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifdef HAVE_DB_185_H + choke me; +#else +#include +#endif +#ifndef DB_VERSION_MAJOR +# define DB_VERSION_MAJOR 1 +#endif +#ifndef NULL +#define NULL ((void *)0) +#endif +main() +{ +#if DB_VERSION_MAJOR > 1 + char *version; + int major, minor, patch; + + version = db_version( &major, &minor, &patch ); + + if( major != DB_VERSION_MAJOR || + minor != DB_VERSION_MINOR || + patch != DB_VERSION_PATCH ) + { + printf("Berkeley DB version mismatch\n" + "\theader: %s\n\tlibrary: %s\n", + DB_VERSION_STRING, version); + return 1; + } +#endif + + return 0; +}]])],[ol_cv_berkeley_db_version=yes],[ol_cv_berkeley_db_version=no],[ol_cv_berkeley_db_version=cross]) + + LIBS="$ol_LIBS" +]) + + if test $ol_cv_berkeley_db_version = no ; then + AC_MSG_ERROR([Berkeley DB version mismatch]) + fi +])dnl +dnl +dnl -------------------------------------------------------------------- +dnl Check if Berkeley DB supports DB_THREAD +AC_DEFUN([OL_BERKELEY_DB_THREAD], +[AC_CACHE_CHECK([for Berkeley DB thread support], [ol_cv_berkeley_db_thread], [ + ol_LIBS="$LIBS" + LIBS="$LTHREAD_LIBS $LIBS" + if test $ol_cv_lib_db != yes ; then + LIBS="$ol_cv_lib_db $LIBS" + fi + + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#ifdef HAVE_DB_185_H + choke me; +#else +#include +#endif +#ifndef NULL +#define NULL ((void *)0) +#endif +main() +{ + int rc; + u_int32_t flags = DB_CREATE | +#ifdef DB_PRIVATE + DB_PRIVATE | +#endif + DB_THREAD; + +#if DB_VERSION_MAJOR > 2 + DB_ENV *env = NULL; + + rc = db_env_create( &env, 0 ); + + flags |= DB_INIT_MPOOL; +#ifdef DB_MPOOL_PRIVATE + flags |= DB_MPOOL_PRIVATE; +#endif + + if( rc ) { + printf("BerkeleyDB: %s\n", db_strerror(rc) ); + return rc; + } + +#if (DB_VERSION_MAJOR > 3) || (DB_VERSION_MINOR >= 1) + rc = (env->open)( env, NULL, flags, 0 ); +#else + rc = (env->open)( env, NULL, NULL, flags, 0 ); +#endif + + if ( rc == 0 ) { + rc = env->close( env, 0 ); + } + + if( rc ) { + printf("BerkeleyDB: %s\n", db_strerror(rc) ); + return rc; + } + +#else + DB_ENV env; + memset( &env, '\0', sizeof(env) ); + + rc = db_appinit( NULL, NULL, &env, flags ); + + if( rc == 0 ) { + db_appexit( &env ); + } + + unlink("__db_mpool.share"); + unlink("__db_lock.share"); +#endif + + return rc; +}]])],[ol_cv_berkeley_db_thread=yes],[ol_cv_berkeley_db_thread=no],[ol_cv_berkeley_db_thread=cross]) + + LIBS="$ol_LIBS" +]) + + if test $ol_cv_berkeley_db_thread != no ; then + AC_DEFINE([HAVE_BERKELEY_DB_THREAD], [1], + [define if Berkeley DB has DB_THREAD support]) + fi +])dnl +dnl +dnl -------------------------------------------------------------------- +dnl Find any DB +AC_DEFUN([OL_BERKELEY_DB], +[ol_cv_berkeley_db=no +AC_CHECK_HEADERS(db.h) +if test $ac_cv_header_db_h = yes; then + OL_BDB_HEADER_VERSION + OL_BDB_COMPAT + + if test $ol_cv_bdb_compat != yes ; then + AC_MSG_ERROR([BerkeleyDB version incompatible with BDB/HDB backends]) + fi + + OL_BERKELEY_DB_LINK + if test "$ol_cv_lib_db" != no ; then + ol_cv_berkeley_db=yes + OL_BERKELEY_DB_VERSION + OL_BERKELEY_DB_THREAD + fi +fi +]) +dnl -------------------------------------------------------------------- +dnl Check for version compatility with back-bdb +AC_DEFUN([OL_BDB_COMPAT], +[AC_CACHE_CHECK([if Berkeley DB version supported by BDB/HDB backends], [ol_cv_bdb_compat],[ + AC_EGREP_CPP(__db_version_compat,[ +#include + + /* this check could be improved */ +#ifndef DB_VERSION_MAJOR +# define DB_VERSION_MAJOR 1 +#endif +#ifndef DB_VERSION_MINOR +# define DB_VERSION_MINOR 0 +#endif + +#define DB_VERSION_MM ((DB_VERSION_MAJOR<<8)|DB_VERSION_MINOR) + +/* require 4.4 or later */ +#if DB_VERSION_MM >= 0x0404 + __db_version_compat +#endif + ], [ol_cv_bdb_compat=yes], [ol_cv_bdb_compat=no])]) +]) + +dnl +dnl ==================================================================== +dnl Check POSIX Thread version +dnl +dnl defines ol_cv_pthread_version to 4, 5, 6, 7, 8, 10, depending on the +dnl version of the POSIX.4a Draft that is implemented. +dnl 10 == POSIX.4a Final == POSIX.1c-1996 for our purposes. +dnl Existence of pthread.h should be tested separately. +dnl +dnl tests: +dnl pthread_detach() was dropped in Draft 8, it is present +dnl in every other version +dnl PTHREAD_CREATE_UNDETACHED is only in Draft 7, it was called +dnl PTHREAD_CREATE_JOINABLE after that +dnl pthread_attr_create was renamed to pthread_attr_init in Draft 6. +dnl Draft 6-10 has _init, Draft 4-5 has _create. +dnl pthread_attr_default was dropped in Draft 6, only 4 and 5 have it +dnl PTHREAD_MUTEX_INITIALIZER was introduced in Draft 5. It's not +dnl interesting to us because we don't try to statically +dnl initialize mutexes. 5-10 has it. +dnl +dnl Draft 9 and 10 are equivalent for our purposes. +dnl +AC_DEFUN([OL_POSIX_THREAD_VERSION], +[AC_CACHE_CHECK([POSIX thread version],[ol_cv_pthread_version],[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +# include + ]], [[ + int i = PTHREAD_CREATE_JOINABLE; + ]])],[ + AC_EGREP_HEADER(pthread_detach,pthread.h, + ol_cv_pthread_version=10, ol_cv_pthread_version=8)],[ + AC_EGREP_CPP(draft7,[ +# include +# ifdef PTHREAD_CREATE_UNDETACHED + draft7 +# endif + ], ol_cv_pthread_version=7, [ + AC_EGREP_HEADER(pthread_attr_init,pthread.h, + ol_cv_pthread_version=6, [ + AC_EGREP_CPP(draft5,[ +# include +#ifdef PTHREAD_MUTEX_INITIALIZER + draft5 +#endif + ], ol_cv_pthread_version=5, ol_cv_pthread_version=4) ]) ]) ]) +]) +])dnl +dnl +dnl -------------------------------------------------------------------- +AC_DEFUN([OL_PTHREAD_TEST_INCLUDES], [[ +/* pthread test headers */ +#include +#if HAVE_PTHREADS < 7 +#include +#endif +#ifndef NULL +#define NULL (void*)0 +#endif + +static void *task(p) + void *p; +{ + return (void *) (p == NULL); +} +]]) +AC_DEFUN([OL_PTHREAD_TEST_FUNCTION],[[ + /* pthread test function */ +#ifndef PTHREAD_CREATE_DETACHED +#define PTHREAD_CREATE_DETACHED 1 +#endif + pthread_t t; + int status; + int detach = PTHREAD_CREATE_DETACHED; + +#if HAVE_PTHREADS > 4 + /* Final pthreads */ + pthread_attr_t attr; + + status = pthread_attr_init(&attr); + if( status ) return status; + +#if HAVE_PTHREADS < 7 + status = pthread_attr_setdetachstate(&attr, &detach); + if( status < 0 ) status = errno; +#else + status = pthread_attr_setdetachstate(&attr, detach); +#endif + if( status ) return status; + status = pthread_create( &t, &attr, task, NULL ); +#if HAVE_PTHREADS < 7 + if( status < 0 ) status = errno; +#endif + if( status ) return status; +#else + /* Draft 4 pthreads */ + status = pthread_create( &t, pthread_attr_default, task, NULL ); + if( status ) return errno; + + /* give thread a chance to complete */ + /* it should remain joinable and hence detachable */ + sleep( 1 ); + + status = pthread_detach( &t ); + if( status ) return errno; +#endif + +#ifdef HAVE_LINUX_THREADS + pthread_kill_other_threads_np(); +#endif + + return 0; +]]) + +AC_DEFUN([OL_PTHREAD_TEST_PROGRAM], [ +AC_LANG_SOURCE([OL_PTHREAD_TEST_INCLUDES + +int main(argc, argv) + int argc; + char **argv; +{ +OL_PTHREAD_TEST_FUNCTION +} +])]) +dnl -------------------------------------------------------------------- +AC_DEFUN([OL_PTHREAD_TRY], [# Pthread try link: $1 ($2) +if test "$ol_link_threads" = no ; then + # try $1 + AC_CACHE_CHECK([for pthread link with $1], [$2], [ + # save the flags + ol_LIBS="$LIBS" + LIBS="$1 $LIBS" + + AC_RUN_IFELSE([OL_PTHREAD_TEST_PROGRAM], + [$2=yes], + [$2=no], + [AC_LINK_IFELSE([AC_LANG_PROGRAM(OL_PTHREAD_TEST_INCLUDES, + OL_PTHREAD_TEST_FUNCTION)], + [$2=yes], [$2=no])]) + + # restore the LIBS + LIBS="$ol_LIBS" + ]) + + if test $$2 = yes ; then + ol_link_pthreads="$1" + ol_link_threads=posix + fi +fi +]) +dnl +dnl ==================================================================== +dnl Check GNU Pth pthread Header +dnl +dnl defines ol_cv_header linux_threads to 'yes' or 'no' +dnl 'no' implies pthreads.h is not LinuxThreads or pthreads.h +dnl doesn't exists. Existance of pthread.h should separately +dnl checked. +dnl +AC_DEFUN([OL_HEADER_GNU_PTH_PTHREAD_H], [ + AC_CACHE_CHECK([for GNU Pth pthread.h], + [ol_cv_header_gnu_pth_pthread_h], + [AC_EGREP_CPP(__gnu_pth__, + [#include +#ifdef _POSIX_THREAD_IS_GNU_PTH + __gnu_pth__; +#endif +], + [ol_cv_header_gnu_pth_pthread_h=yes], + [ol_cv_header_gnu_pth_pthread_h=no]) + ]) +])dnl +dnl ==================================================================== +dnl Check for NT Threads +AC_DEFUN([OL_NT_THREADS], [ + AC_CHECK_FUNC(_beginthread) + + if test $ac_cv_func__beginthread = yes ; then + AC_DEFINE([HAVE_NT_THREADS], [1], [if you have NT Threads]) + ol_cv_nt_threads=yes + fi +]) +dnl ==================================================================== +dnl Check LinuxThreads Header +dnl +dnl defines ol_cv_header linux_threads to 'yes' or 'no' +dnl 'no' implies pthreads.h is not LinuxThreads or pthreads.h +dnl doesn't exists. Existance of pthread.h should separately +dnl checked. +dnl +AC_DEFUN([OL_HEADER_LINUX_THREADS], [ + AC_CACHE_CHECK([for LinuxThreads pthread.h], + [ol_cv_header_linux_threads], + [AC_EGREP_CPP(pthread_kill_other_threads_np, + [#include ], + [ol_cv_header_linux_threads=yes], + [ol_cv_header_linux_threads=no]) + ]) + if test $ol_cv_header_linux_threads = yes; then + AC_DEFINE([HAVE_LINUX_THREADS], [1], [if you have LinuxThreads]) + fi +])dnl +dnl -------------------------------------------------------------------- +dnl Check LinuxThreads Implementation +dnl +dnl defines ol_cv_sys_linux_threads to 'yes' or 'no' +dnl 'no' implies pthreads implementation is not LinuxThreads. +dnl +AC_DEFUN([OL_SYS_LINUX_THREADS], [ + AC_CHECK_FUNCS(pthread_kill_other_threads_np) + AC_CACHE_CHECK([for LinuxThreads implementation], + [ol_cv_sys_linux_threads], + [ol_cv_sys_linux_threads=$ac_cv_func_pthread_kill_other_threads_np]) +])dnl +dnl +dnl -------------------------------------------------------------------- +dnl Check LinuxThreads consistency +AC_DEFUN([OL_LINUX_THREADS], [ + AC_REQUIRE([OL_HEADER_LINUX_THREADS]) + AC_REQUIRE([OL_SYS_LINUX_THREADS]) + AC_CACHE_CHECK([for LinuxThreads consistency], [ol_cv_linux_threads], [ + if test $ol_cv_header_linux_threads = yes && + test $ol_cv_sys_linux_threads = yes; then + ol_cv_linux_threads=yes + elif test $ol_cv_header_linux_threads = no && + test $ol_cv_sys_linux_threads = no; then + ol_cv_linux_threads=no + else + ol_cv_linux_threads=error + fi + ]) +])dnl +dnl +dnl ==================================================================== +dnl Check for POSIX Regex +AC_DEFUN([OL_POSIX_REGEX], [ +AC_CACHE_CHECK([for compatible POSIX regex],ol_cv_c_posix_regex,[ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +#include +static char *pattern, *string; +main() +{ + int rc; + regex_t re; + + pattern = "^A"; + + if(regcomp(&re, pattern, 0)) { + return -1; + } + + string = "ALL MATCH"; + + rc = regexec(&re, string, 0, (void*)0, 0); + + regfree(&re); + + return rc; +}]])],[ol_cv_c_posix_regex=yes],[ol_cv_c_posix_regex=no],[ol_cv_c_posix_regex=cross])]) +]) +dnl +dnl ==================================================================== +dnl Check if toupper() requires islower() to be called first +AC_DEFUN([OL_C_UPPER_LOWER], +[AC_CACHE_CHECK([if toupper() requires islower()],ol_cv_c_upper_lower,[ + AC_RUN_IFELSE([AC_LANG_SOURCE([[ +#include +main() +{ + if ('C' == toupper('C')) + exit(0); + else + exit(1); +}]])],[ol_cv_c_upper_lower=no],[ol_cv_c_upper_lower=yes],[ol_cv_c_upper_lower=safe])]) +if test $ol_cv_c_upper_lower != no ; then + AC_DEFINE([C_UPPER_LOWER], [1], [define if toupper() requires islower()]) +fi +]) +dnl +dnl ==================================================================== +dnl Error string checks +dnl +dnl Check for declaration of sys_errlist in one of stdio.h and errno.h. +dnl Declaration of sys_errlist on BSD4.4 interferes with our declaration. +dnl Reported by Keith Bostic. +AC_DEFUN([OL_SYS_ERRLIST], +[AC_CACHE_CHECK([declaration of sys_errlist],ol_cv_dcl_sys_errlist,[ + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ +#include +#include +#include +#ifdef _WIN32 +#include +#endif ]], [[char *c = (char *) *sys_errlist]])],[ol_cv_dcl_sys_errlist=yes + ol_cv_have_sys_errlist=yes],[ol_cv_dcl_sys_errlist=no])]) +# +# It's possible (for near-UNIX clones) that sys_errlist doesn't exist +if test $ol_cv_dcl_sys_errlist = no ; then + AC_DEFINE([DECL_SYS_ERRLIST], [1], + [define if sys_errlist is not declared in stdio.h or errno.h]) + + AC_CACHE_CHECK([existence of sys_errlist],ol_cv_have_sys_errlist,[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[char *c = (char *) *sys_errlist]])],[ol_cv_have_sys_errlist=yes],[ol_cv_have_sys_errlist=no])]) +fi +if test $ol_cv_have_sys_errlist = yes ; then + AC_DEFINE([HAVE_SYS_ERRLIST], [1], + [define if you actually have sys_errlist in your libs]) +fi +])dnl +AC_DEFUN([OL_NONPOSIX_STRERROR_R], +[AC_CACHE_CHECK([non-posix strerror_r],ol_cv_nonposix_strerror_r,[ + AC_EGREP_CPP(strerror_r,[#include ], + ol_decl_strerror_r=yes, ol_decl_strerror_r=no)dnl + + if test $ol_decl_strerror_r = yes ; then + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ /* from autoconf 2.59 */ + char buf[100]; + char x = *strerror_r (0, buf, sizeof buf); + char *p = strerror_r (0, buf, sizeof buf); + ]])],[ol_cv_nonposix_strerror_r=yes],[ol_cv_nonposix_strerror_r=no]) + else + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + main() { + char buf[100]; + buf[0] = 0; + strerror_r( 1, buf, sizeof buf ); + exit( buf[0] == 0 ); + } + ]])],[ol_cv_nonposix_strerror_r=yes],[ol_cv_nonposix_strerror=no],[ol_cv_nonposix_strerror=no]) + fi + ]) +if test $ol_cv_nonposix_strerror_r = yes ; then + AC_DEFINE([HAVE_NONPOSIX_STRERROR_R], [1], + [define if strerror_r returns char* instead of int]) +fi +])dnl +dnl +AC_DEFUN([OL_STRERROR], +[OL_SYS_ERRLIST dnl TEMPORARY +AC_CHECK_FUNCS(strerror strerror_r) +ol_cv_func_strerror_r=no +if test "${ac_cv_func_strerror_r}" = yes ; then + OL_NONPOSIX_STRERROR_R +elif test "${ac_cv_func_strerror}" = no ; then + OL_SYS_ERRLIST +fi +])dnl +dnl ==================================================================== +dnl Early MIPS compilers (used in Ultrix 4.2) don't like +dnl "int x; int *volatile a = &x; *a = 0;" +dnl -- borrowed from PDKSH +AC_DEFUN([OL_C_VOLATILE], + [AC_CACHE_CHECK(if compiler understands volatile, ol_cv_c_volatile, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[int x, y, z;]], [[volatile int a; int * volatile b = x ? &y : &z; + /* Older MIPS compilers (eg., in Ultrix 4.2) don't like *b = 0 */ + *b = 0;]])],[ol_cv_c_volatile=yes],[ol_cv_c_volatile=no])]) + if test $ol_cv_c_volatile = yes; then + : + else + AC_DEFINE([volatile], [], [define as empty if volatile is not supported]) + fi + ])dnl +dnl +dnl ==================================================================== +dnl Look for fetch(3) +AC_DEFUN([OL_LIB_FETCH], +[ol_LIBS=$LIBS +LIBS="-lfetch -lcom_err $LIBS" +AC_CACHE_CHECK([fetch(3) library],ol_cv_lib_fetch,[ + AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_PARAM_H +#include +#endif +#include +#include ]], [[struct url *u = fetchParseURL("file:///"); ]])],[ol_cv_lib_fetch=yes],[ol_cv_lib_fetch=no])]) +LIBS=$ol_LIBS +if test $ol_cv_lib_fetch != no ; then + ol_link_fetch="-lfetch -lcom_err" + AC_DEFINE([HAVE_FETCH], [1], + [define if you actually have FreeBSD fetch(3)]) +fi +])dnl +dnl +dnl ==================================================================== +dnl Define inet_aton is available +AC_DEFUN([OL_FUNC_INET_ATON], + [AC_CACHE_CHECK([for inet_aton()], ol_cv_func_inet_aton, + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[ +#ifdef HAVE_SYS_TYPES_H +# include +#endif +#ifdef HAVE_SYS_SOCKET_H +# include +# ifdef HAVE_SYS_SELECT_H +# include +# endif +# include +# ifdef HAVE_ARPA_INET_H +# include +# endif +#endif +]], [[struct in_addr in; +int rc = inet_aton( "255.255.255.255", &in );]])],[ol_cv_func_inet_aton=yes],[ol_cv_func_inet_aton=no])]) + if test $ol_cv_func_inet_aton != no; then + AC_DEFINE(HAVE_INET_ATON, 1, + [define to you inet_aton(3) is available]) + fi + ])dnl +dnl +dnl ==================================================================== +dnl check no of arguments for ctime_r +AC_DEFUN([OL_FUNC_CTIME_R_NARGS], + [AC_CACHE_CHECK(number of arguments of ctime_r, ol_cv_func_ctime_r_nargs, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[time_t ti; char *buffer; ctime_r(&ti,buffer,32);]])],[ol_cv_func_ctime_r_nargs3=yes],[ol_cv_func_ctime_r_nargs3=no]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[time_t ti; char *buffer; ctime_r(&ti,buffer);]])],[ol_cv_func_ctime_r_nargs2=yes],[ol_cv_func_ctime_r_nargs2=no]) + + if test $ol_cv_func_ctime_r_nargs3 = yes && + test $ol_cv_func_ctime_r_nargs2 = no ; then + + ol_cv_func_ctime_r_nargs=3 + + elif test $ol_cv_func_ctime_r_nargs3 = no && + test $ol_cv_func_ctime_r_nargs2 = yes ; then + + ol_cv_func_ctime_r_nargs=2 + + else + ol_cv_func_ctime_r_nargs=0 + fi + ]) + + if test $ol_cv_func_ctime_r_nargs -gt 1 ; then + AC_DEFINE_UNQUOTED(CTIME_R_NARGS, $ol_cv_func_ctime_r_nargs, + [set to the number of arguments ctime_r() expects]) + fi +])dnl +dnl +dnl -------------------------------------------------------------------- +dnl check return type of ctime_r() +AC_DEFUN([OL_FUNC_CTIME_R_TYPE], + [AC_CACHE_CHECK(return type of ctime_r, ol_cv_func_ctime_r_type, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[extern int (ctime_r)();]])],[ol_cv_func_ctime_r_type="int"],[ol_cv_func_ctime_r_type="charp"]) + ]) + if test $ol_cv_func_ctime_r_type = "int" ; then + AC_DEFINE(CTIME_R_RETURNS_INT,1, [define if ctime_r() returns int]) + fi +])dnl +dnl ==================================================================== +dnl check no of arguments for gethostbyname_r +AC_DEFUN([OL_FUNC_GETHOSTBYNAME_R_NARGS], + [AC_CACHE_CHECK(number of arguments of gethostbyname_r, + ol_cv_func_gethostbyname_r_nargs, + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +#include +#include +#include +#define BUFSIZE (sizeof(struct hostent)+10)]], [[struct hostent hent; char buffer[BUFSIZE]; + int bufsize=BUFSIZE;int h_errno; + (void)gethostbyname_r("segovia.cs.purdue.edu", &hent, + buffer, bufsize, &h_errno);]])],[ol_cv_func_gethostbyname_r_nargs5=yes],[ol_cv_func_gethostbyname_r_nargs5=no]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +#include +#include +#include +#define BUFSIZE (sizeof(struct hostent)+10)]], [[struct hostent hent;struct hostent *rhent; + char buffer[BUFSIZE]; + int bufsize=BUFSIZE;int h_errno; + (void)gethostbyname_r("localhost", &hent, buffer, bufsize, + &rhent, &h_errno);]])],[ol_cv_func_gethostbyname_r_nargs6=yes],[ol_cv_func_gethostbyname_r_nargs6=no]) + + if test $ol_cv_func_gethostbyname_r_nargs5 = yes && + test $ol_cv_func_gethostbyname_r_nargs6 = no ; then + + ol_cv_func_gethostbyname_r_nargs=5 + + elif test $ol_cv_func_gethostbyname_r_nargs5 = no && + test $ol_cv_func_gethostbyname_r_nargs6 = yes ; then + + ol_cv_func_gethostbyname_r_nargs=6 + + else + ol_cv_func_gethostbyname_r_nargs=0 + fi + ]) + if test $ol_cv_func_gethostbyname_r_nargs -gt 1 ; then + AC_DEFINE_UNQUOTED(GETHOSTBYNAME_R_NARGS, + $ol_cv_func_gethostbyname_r_nargs, + [set to the number of arguments gethostbyname_r() expects]) + fi +])dnl +dnl +dnl check no of arguments for gethostbyaddr_r +AC_DEFUN([OL_FUNC_GETHOSTBYADDR_R_NARGS], + [AC_CACHE_CHECK(number of arguments of gethostbyaddr_r, + [ol_cv_func_gethostbyaddr_r_nargs], + [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +#include +#include +#include +#define BUFSIZE (sizeof(struct hostent)+10)]], [[struct hostent hent; char buffer[BUFSIZE]; + struct in_addr add; + size_t alen=sizeof(struct in_addr); + int bufsize=BUFSIZE;int h_errno; + (void)gethostbyaddr_r( (void *)&(add.s_addr), + alen, AF_INET, &hent, buffer, bufsize, &h_errno);]])],[ol_cv_func_gethostbyaddr_r_nargs7=yes],[ol_cv_func_gethostbyaddr_r_nargs7=no]) + + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +#include +#include +#include +#define BUFSIZE (sizeof(struct hostent)+10)]], [[struct hostent hent; + struct hostent *rhent; char buffer[BUFSIZE]; + struct in_addr add; + size_t alen=sizeof(struct in_addr); + int bufsize=BUFSIZE;int h_errno; + (void)gethostbyaddr_r( (void *)&(add.s_addr), + alen, AF_INET, &hent, buffer, bufsize, + &rhent, &h_errno);]])],[ol_cv_func_gethostbyaddr_r_nargs8=yes],[ol_cv_func_gethostbyaddr_r_nargs8=no]) + + if test $ol_cv_func_gethostbyaddr_r_nargs7 = yes && + test $ol_cv_func_gethostbyaddr_r_nargs8 = no ; then + + ol_cv_func_gethostbyaddr_r_nargs=7 + + elif test $ol_cv_func_gethostbyaddr_r_nargs7 = no && + test $ol_cv_func_gethostbyaddr_r_nargs8 = yes ; then + + ol_cv_func_gethostbyaddr_r_nargs=8 + + else + ol_cv_func_gethostbyaddr_r_nargs=0 + fi + ]) + if test $ol_cv_func_gethostbyaddr_r_nargs -gt 1 ; then + AC_DEFINE_UNQUOTED(GETHOSTBYADDR_R_NARGS, + $ol_cv_func_gethostbyaddr_r_nargs, + [set to the number of arguments gethostbyaddr_r() expects]) + fi +])dnl +dnl +dnl -------------------------------------------------------------------- +dnl Check for Cyrus SASL version compatility +AC_DEFUN([OL_SASL_COMPAT], +[AC_CACHE_CHECK([Cyrus SASL library version], [ol_cv_sasl_compat],[ + AC_EGREP_CPP(__sasl_compat,[ +#ifdef HAVE_SASL_SASL_H +#include +#else +#include +#endif + +/* Require 2.1.15+ */ +#if SASL_VERSION_MAJOR == 2 && SASL_VERSION_MINOR > 1 + char *__sasl_compat = "2.2+ or better okay (we guess)"; +#elif SASL_VERSION_MAJOR == 2 && SASL_VERSION_MINOR == 1 \ + && SASL_VERSION_STEP >=15 + char *__sasl_compat = "2.1.15+ or better okay"; +#endif + ], [ol_cv_sasl_compat=yes], [ol_cv_sasl_compat=no])]) +]) +dnl ==================================================================== +dnl check for SSL compatibility +AC_DEFUN([OL_SSL_COMPAT], +[AC_CACHE_CHECK([OpenSSL library version (CRL checking capability)], + [ol_cv_ssl_crl_compat],[ + AC_EGREP_CPP(__ssl_compat,[ +#ifdef HAVE_OPENSSL_SSL_H +#include +#endif + +/* Require 0.9.7d+ */ +#if OPENSSL_VERSION_NUMBER >= 0x0090704fL + char *__ssl_compat = "0.9.7d"; +#endif + ], [ol_cv_ssl_crl_compat=yes], [ol_cv_ssl_crl_compat=no])]) +]) diff --git a/sntp/libevent/sample/Makefile.am b/sntp/libevent/sample/Makefile.am index 0071d26f2..2d616f9eb 100644 --- a/sntp/libevent/sample/Makefile.am +++ b/sntp/libevent/sample/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = foreign no-dependencies -LDADD = ../libevent.la +LDADD = @LIBEVENT_GC_SECTIONS@ ../libevent.la AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include noinst_PROGRAMS = event-test time-test signal-test dns-example hello-world http-server diff --git a/sntp/libevent/sample/dns-example.c b/sntp/libevent/sample/dns-example.c index 553182157..e555af562 100644 --- a/sntp/libevent/sample/dns-example.c +++ b/sntp/libevent/sample/dns-example.c @@ -7,6 +7,8 @@ #include +#include "../ipv6-internal.h" + #include #ifdef WIN32 diff --git a/sntp/libevent/sample/hello-world.c b/sntp/libevent/sample/hello-world.c index 90df85f70..d40af5296 100644 --- a/sntp/libevent/sample/hello-world.c +++ b/sntp/libevent/sample/hello-world.c @@ -13,6 +13,9 @@ #include #ifndef WIN32 #include +# ifdef _XOPEN_SOURCE_EXTENDED +# include +# endif #include #endif diff --git a/sntp/libevent/sample/http-server.c b/sntp/libevent/sample/http-server.c index f9e84d1c9..0739b21db 100644 --- a/sntp/libevent/sample/http-server.c +++ b/sntp/libevent/sample/http-server.c @@ -36,8 +36,13 @@ #ifdef _EVENT_HAVE_NETINET_IN_H #include +# ifdef _XOPEN_SOURCE_EXTENDED +# include +# endif #endif +#include <../util-internal.h> + #ifdef WIN32 #define stat _stat #define fstat _fstat @@ -366,9 +371,11 @@ main(int argc, char **argv) if (ss.ss_family == AF_INET) { got_port = ntohs(((struct sockaddr_in*)&ss)->sin_port); inaddr = &((struct sockaddr_in*)&ss)->sin_addr; +#ifdef AF_INET6 } else if (ss.ss_family == AF_INET6) { got_port = ntohs(((struct sockaddr_in6*)&ss)->sin6_port); inaddr = &((struct sockaddr_in6*)&ss)->sin6_addr; +#endif } else { fprintf(stderr, "Weird address family %d\n", ss.ss_family); diff --git a/sntp/libevent/select.c b/sntp/libevent/select.c index 527462ca2..949563181 100644 --- a/sntp/libevent/select.c +++ b/sntp/libevent/select.c @@ -90,6 +90,7 @@ const struct eventop selectops = { }; static int select_resize(struct selectop *sop, int fdsz); +static void select_free_selectop(struct selectop *sop); static void * select_init(struct event_base *base) @@ -99,7 +100,10 @@ select_init(struct event_base *base) if (!(sop = mm_calloc(1, sizeof(struct selectop)))) return (NULL); - select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask)); + if (select_resize(sop, howmany(32 + 1, NFDBITS)*sizeof(fd_mask))) { + select_free_selectop(sop); + return (NULL); + } evsig_init(base); @@ -128,11 +132,14 @@ select_dispatch(struct event_base *base, struct timeval *tv) size_t sz = sop->event_fdsz; if (!(readset_out = mm_realloc(sop->event_readset_out, sz))) return (-1); + sop->event_readset_out = readset_out; if (!(writeset_out = mm_realloc(sop->event_writeset_out, sz))) { - mm_free(readset_out); + /* We don't free readset_out here, since it was + * already successfully reallocated. The next time + * we call select_dispatch, the realloc will be a + * no-op. */ return (-1); } - sop->event_readset_out = readset_out; sop->event_writeset_out = writeset_out; sop->resize_out_sets = 0; } @@ -185,7 +192,6 @@ select_dispatch(struct event_base *base, struct timeval *tv) return (0); } - static int select_resize(struct selectop *sop, int fdsz) { @@ -198,8 +204,15 @@ select_resize(struct selectop *sop, int fdsz) if ((readset_in = mm_realloc(sop->event_readset_in, fdsz)) == NULL) goto error; sop->event_readset_in = readset_in; - if ((writeset_in = mm_realloc(sop->event_writeset_in, fdsz)) == NULL) + if ((writeset_in = mm_realloc(sop->event_writeset_in, fdsz)) == NULL) { + /* Note that this will leave event_readset_in expanded. + * That's okay; we wouldn't want to free it, since that would + * change the semantics of select_resize from "expand the + * readset_in and writeset_in, or return -1" to "expand the + * *set_in members, or trash them and return -1." + */ goto error; + } sop->event_writeset_in = writeset_in; sop->resize_out_sets = 1; @@ -292,11 +305,8 @@ select_del(struct event_base *base, int fd, short old, short events, void *p) } static void -select_dealloc(struct event_base *base) +select_free_selectop(struct selectop *sop) { - struct selectop *sop = base->evbase; - - evsig_dealloc(base); if (sop->event_readset_in) mm_free(sop->event_readset_in); if (sop->event_writeset_in) @@ -309,3 +319,11 @@ select_dealloc(struct event_base *base) memset(sop, 0, sizeof(struct selectop)); mm_free(sop); } + +static void +select_dealloc(struct event_base *base) +{ + evsig_dealloc(base); + + select_free_selectop(base->evbase); +} diff --git a/sntp/libevent/test/Makefile.am b/sntp/libevent/test/Makefile.am index 97682fb46..abcb18ce9 100644 --- a/sntp/libevent/test/Makefile.am +++ b/sntp/libevent/test/Makefile.am @@ -1,17 +1,22 @@ AUTOMAKE_OPTIONS = foreign -AM_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include -DTINYTEST_LOCAL +AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat -I$(top_srcdir)/include -I../include -DTINYTEST_LOCAL EXTRA_DIST = regress.rpc regress.gen.h regress.gen.c test.sh -noinst_PROGRAMS = test-init test-eof test-weof test-time regress \ +noinst_PROGRAMS = test-init test-eof test-weof test-time @CHECK_REGRESS@ \ bench bench_cascade bench_http bench_httpclient test-ratelim \ test-changelist +EXTRA_PROGRAMS = regress noinst_HEADERS = tinytest.h tinytest_macros.h regress.h tinytest_local.h TESTS = $(top_srcdir)/test/test.sh -BUILT_SOURCES = regress.gen.c regress.gen.h +BUILT_SOURCES = +if BUILD_REGRESS +BUILT_SOURCES += regress.gen.c regress.gen.h +endif + test_init_SOURCES = test-init.c test_init_LDADD = ../libevent_core.la test_eof_SOURCES = test-eof.c @@ -45,7 +50,7 @@ if BUILD_WIN32 regress_SOURCES += regress_iocp.c endif -regress_LDADD = ../libevent.la $(PTHREAD_LIBS) $(ZLIB_LIBS) +regress_LDADD = @LIBEVENT_GC_SECTIONS@ ../libevent.la $(PTHREAD_LIBS) $(ZLIB_LIBS) regress_CFLAGS = -I$(top_srcdir) -I$(top_srcdir)/compat \ -I$(top_srcdir)/include -I../include $(PTHREAD_CFLAGS) $(ZLIB_CFLAGS) regress_LDFLAGS = $(PTHREAD_CFLAGS) @@ -56,13 +61,13 @@ regress_LDADD += ../libevent_openssl.la -lcrypto -lssl endif bench_SOURCES = bench.c -bench_LDADD = ../libevent.la +bench_LDADD = @LIBEVENT_GC_SECTIONS@ ../libevent.la bench_cascade_SOURCES = bench_cascade.c -bench_cascade_LDADD = ../libevent.la +bench_cascade_LDADD = @LIBEVENT_GC_SECTIONS@ ../libevent.la bench_http_SOURCES = bench_http.c -bench_http_LDADD = ../libevent.la +bench_http_LDADD = @LIBEVENT_GC_SECTIONS@ ../libevent.la bench_httpclient_SOURCES = bench_httpclient.c -bench_httpclient_LDADD = ../libevent_core.la +bench_httpclient_LDADD = @LIBEVENT_GC_SECTIONS@ ../libevent_core.la regress.gen.c regress.gen.h: regress.rpc $(top_srcdir)/event_rpcgen.py $(top_srcdir)/event_rpcgen.py $(srcdir)/regress.rpc || echo "No Python installed" diff --git a/sntp/libevent/test/bench_httpclient.c b/sntp/libevent/test/bench_httpclient.c index 19f025f18..f0888e6ca 100644 --- a/sntp/libevent/test/bench_httpclient.c +++ b/sntp/libevent/test/bench_httpclient.c @@ -31,6 +31,9 @@ #else #include #include +# ifdef _XOPEN_SOURCE_EXTENDED +# include +# endif #endif #include #include diff --git a/sntp/libevent/test/regress.gen.c b/sntp/libevent/test/regress.gen.c deleted file mode 100644 index c7e655851..000000000 --- a/sntp/libevent/test/regress.gen.c +++ /dev/null @@ -1,1225 +0,0 @@ -/* - * Automatically generated from ../../../../../sntp/build-libevent/../libevent/test/regress.rpc - * by event_rpcgen.py/0.1. DO NOT EDIT THIS FILE. - */ - -#include -#include -#include -#include -#include -#include -#include - -#ifdef _EVENT___func__ -#define __func__ _EVENT___func__ -#endif - - -#include "regress.gen.h" - -void event_warn(const char *fmt, ...); -void event_warnx(const char *fmt, ...); - - -/* - * Implementation of msg - */ - -static struct msg_access_ __msg_base = { - msg_from_name_assign, - msg_from_name_get, - msg_to_name_assign, - msg_to_name_get, - msg_attack_assign, - msg_attack_get, - msg_run_assign, - msg_run_get, - msg_run_add, -}; - -struct msg * -msg_new(void) -{ - return msg_new_with_arg(NULL); -} - -struct msg * -msg_new_with_arg(void *unused) -{ - struct msg *tmp; - if ((tmp = malloc(sizeof(struct msg))) == NULL) { - event_warn("%s: malloc", __func__); - return (NULL); - } - tmp->base = &__msg_base; - - tmp->from_name_data = NULL; - tmp->from_name_set = 0; - - tmp->to_name_data = NULL; - tmp->to_name_set = 0; - - tmp->attack_data = NULL; - tmp->attack_set = 0; - - tmp->run_data = NULL; - tmp->run_length = 0; - tmp->run_num_allocated = 0; - tmp->run_set = 0; - - return (tmp); -} - - - - -static int -msg_run_expand_to_hold_more(struct msg *msg) -{ - int tobe_allocated = msg->run_num_allocated; - struct run** new_data = NULL; - tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1; - new_data = (struct run**) realloc(msg->run_data, - tobe_allocated * sizeof(struct run*)); - if (new_data == NULL) - return -1; - msg->run_data = new_data; - msg->run_num_allocated = tobe_allocated; - return 0;} - -struct run* -msg_run_add(struct msg *msg) -{ - if (++msg->run_length >= msg->run_num_allocated) { - if (msg_run_expand_to_hold_more(msg)<0) - goto error; - } - msg->run_data[msg->run_length - 1] = run_new(); - if (msg->run_data[msg->run_length - 1] == NULL) - goto error; - msg->run_set = 1; - return (msg->run_data[msg->run_length - 1]); -error: - --msg->run_length; - return (NULL); -} - -int -msg_from_name_assign(struct msg *msg, - const char * value) -{ - if (msg->from_name_data != NULL) - free(msg->from_name_data); - if ((msg->from_name_data = strdup(value)) == NULL) - return (-1); - msg->from_name_set = 1; - return (0); -} - -int -msg_to_name_assign(struct msg *msg, - const char * value) -{ - if (msg->to_name_data != NULL) - free(msg->to_name_data); - if ((msg->to_name_data = strdup(value)) == NULL) - return (-1); - msg->to_name_set = 1; - return (0); -} - -int -msg_attack_assign(struct msg *msg, - const struct kill* value) -{ - struct evbuffer *tmp = NULL; - if (msg->attack_set) { - kill_clear(msg->attack_data); - msg->attack_set = 0; - } else { - msg->attack_data = kill_new(); - if (msg->attack_data == NULL) { - event_warn("%s: kill_new()", __func__); - goto error; - } - } - if ((tmp = evbuffer_new()) == NULL) { - event_warn("%s: evbuffer_new()", __func__); - goto error; - } - kill_marshal(tmp, value); - if (kill_unmarshal(msg->attack_data, tmp) == -1) { - event_warnx("%s: kill_unmarshal", __func__); - goto error; - } - msg->attack_set = 1; - evbuffer_free(tmp); - return (0); - error: - if (tmp != NULL) - evbuffer_free(tmp); - if (msg->attack_data != NULL) { - kill_free(msg->attack_data); - msg->attack_data = NULL; - } - return (-1); -} - -int -msg_run_assign(struct msg *msg, int off, - const struct run* value) -{ - if (!msg->run_set || off < 0 || off >= msg->run_length) - return (-1); - - { - int had_error = 0; - struct evbuffer *tmp = NULL; - run_clear(msg->run_data[off]); - if ((tmp = evbuffer_new()) == NULL) { - event_warn("%s: evbuffer_new()", __func__); - had_error = 1; - goto done; - } - run_marshal(tmp, value); - if (run_unmarshal(msg->run_data[off], tmp) == -1) { - event_warnx("%s: run_unmarshal", __func__); - had_error = 1; - goto done; - } - done:if (tmp != NULL) - evbuffer_free(tmp); - if (had_error) { - run_clear(msg->run_data[off]); - return (-1); - } - } - return (0); -} - -int -msg_from_name_get(struct msg *msg, char * *value) -{ - if (msg->from_name_set != 1) - return (-1); - *value = msg->from_name_data; - return (0); -} - -int -msg_to_name_get(struct msg *msg, char * *value) -{ - if (msg->to_name_set != 1) - return (-1); - *value = msg->to_name_data; - return (0); -} - -int -msg_attack_get(struct msg *msg, struct kill* *value) -{ - if (msg->attack_set != 1) { - msg->attack_data = kill_new(); - if (msg->attack_data == NULL) - return (-1); - msg->attack_set = 1; - } - *value = msg->attack_data; - return (0); -} - -int -msg_run_get(struct msg *msg, int offset, - struct run* *value) -{ - if (!msg->run_set || offset < 0 || offset >= msg->run_length) - return (-1); - *value = msg->run_data[offset]; - return (0); -} - -void -msg_clear(struct msg *tmp) -{ - if (tmp->from_name_set == 1) { - free(tmp->from_name_data); - tmp->from_name_data = NULL; - tmp->from_name_set = 0; - } - if (tmp->to_name_set == 1) { - free(tmp->to_name_data); - tmp->to_name_data = NULL; - tmp->to_name_set = 0; - } - if (tmp->attack_set == 1) { - kill_free(tmp->attack_data); - tmp->attack_data = NULL; - tmp->attack_set = 0; - } - if (tmp->run_set == 1) { - int i; - for (i = 0; i < tmp->run_length; ++i) { - run_free(tmp->run_data[i]); - } - free(tmp->run_data); - tmp->run_data = NULL; - tmp->run_set = 0; - tmp->run_length = 0; - tmp->run_num_allocated = 0; - } -} - -void -msg_free(struct msg *tmp) -{ - if (tmp->from_name_data != NULL) - free (tmp->from_name_data); - if (tmp->to_name_data != NULL) - free (tmp->to_name_data); - if (tmp->attack_data != NULL) - kill_free(tmp->attack_data); - if (tmp->run_set == 1) { - int i; - for (i = 0; i < tmp->run_length; ++i) { - run_free(tmp->run_data[i]); - } - free(tmp->run_data); - tmp->run_data = NULL; - tmp->run_set = 0; - tmp->run_length = 0; - tmp->run_num_allocated = 0; - } - free(tmp->run_data); - free(tmp); -} - -void -msg_marshal(struct evbuffer *evbuf, const struct msg *tmp){ - evtag_marshal_string(evbuf, MSG_FROM_NAME, tmp->from_name_data); - evtag_marshal_string(evbuf, MSG_TO_NAME, tmp->to_name_data); - if (tmp->attack_set) { - evtag_marshal_kill(evbuf, MSG_ATTACK, tmp->attack_data); - } - if (tmp->run_set) { - { - int i; - for (i = 0; i < tmp->run_length; ++i) { - evtag_marshal_run(evbuf, MSG_RUN, tmp->run_data[i]); - } - } - } -} - -int -msg_unmarshal(struct msg *tmp, struct evbuffer *evbuf) -{ - ev_uint32_t tag; - while (evbuffer_get_length(evbuf) > 0) { - if (evtag_peek(evbuf, &tag) == -1) - return (-1); - switch (tag) { - - case MSG_FROM_NAME: - - if (tmp->from_name_set) - return (-1); - if (evtag_unmarshal_string(evbuf, MSG_FROM_NAME, &tmp->from_name_data) == -1) { - event_warnx("%s: failed to unmarshal from_name", __func__); - return (-1); - } - tmp->from_name_set = 1; - break; - - case MSG_TO_NAME: - - if (tmp->to_name_set) - return (-1); - if (evtag_unmarshal_string(evbuf, MSG_TO_NAME, &tmp->to_name_data) == -1) { - event_warnx("%s: failed to unmarshal to_name", __func__); - return (-1); - } - tmp->to_name_set = 1; - break; - - case MSG_ATTACK: - - if (tmp->attack_set) - return (-1); - tmp->attack_data = kill_new(); - if (tmp->attack_data == NULL) - return (-1); - if (evtag_unmarshal_kill(evbuf, MSG_ATTACK, tmp->attack_data) == -1) { - event_warnx("%s: failed to unmarshal attack", __func__); - return (-1); - } - tmp->attack_set = 1; - break; - - case MSG_RUN: - - if (tmp->run_length >= tmp->run_num_allocated && - msg_run_expand_to_hold_more(tmp) < 0) { - puts("HEY NOW"); - return (-1); - } - tmp->run_data[tmp->run_length] = run_new(); - if (tmp->run_data[tmp->run_length] == NULL) - return (-1); - if (evtag_unmarshal_run(evbuf, MSG_RUN, tmp->run_data[tmp->run_length]) == -1) { - event_warnx("%s: failed to unmarshal run", __func__); - return (-1); - } - ++tmp->run_length; - tmp->run_set = 1; - break; - - default: - return -1; - } - } - - if (msg_complete(tmp) == -1) - return (-1); - return (0); -} - -int -msg_complete(struct msg *msg) -{ - if (!msg->from_name_set) - return (-1); - if (!msg->to_name_set) - return (-1); - if (msg->attack_set && kill_complete(msg->attack_data) == -1) - return (-1); - { - int i; - for (i = 0; i < msg->run_length; ++i) { - if (msg->run_set && run_complete(msg->run_data[i]) == -1) - return (-1); - } - } - return (0); -} - -int -evtag_unmarshal_msg(struct evbuffer *evbuf, ev_uint32_t need_tag, struct msg *msg) -{ - ev_uint32_t tag; - int res = -1; - - struct evbuffer *tmp = evbuffer_new(); - - if (evtag_unmarshal(evbuf, &tag, tmp) == -1 || tag != need_tag) - goto error; - - if (msg_unmarshal(msg, tmp) == -1) - goto error; - - res = 0; - - error: - evbuffer_free(tmp); - return (res); -} - -void -evtag_marshal_msg(struct evbuffer *evbuf, ev_uint32_t tag, const struct msg *msg) -{ - struct evbuffer *_buf = evbuffer_new(); - assert(_buf != NULL); - msg_marshal(_buf, msg); - evtag_marshal_buffer(evbuf, tag, _buf); - evbuffer_free(_buf); -} - -/* - * Implementation of kill - */ - -static struct kill_access_ __kill_base = { - kill_weapon_assign, - kill_weapon_get, - kill_action_assign, - kill_action_get, - kill_how_often_assign, - kill_how_often_get, - kill_how_often_add, -}; - -struct kill * -kill_new(void) -{ - return kill_new_with_arg(NULL); -} - -struct kill * -kill_new_with_arg(void *unused) -{ - struct kill *tmp; - if ((tmp = malloc(sizeof(struct kill))) == NULL) { - event_warn("%s: malloc", __func__); - return (NULL); - } - tmp->base = &__kill_base; - - tmp->weapon_data = NULL; - tmp->weapon_set = 0; - - tmp->action_data = NULL; - tmp->action_set = 0; - - tmp->how_often_data = NULL; - tmp->how_often_length = 0; - tmp->how_often_num_allocated = 0; - tmp->how_often_set = 0; - - return (tmp); -} - - - -static int -kill_how_often_expand_to_hold_more(struct kill *msg) -{ - int tobe_allocated = msg->how_often_num_allocated; - ev_uint32_t* new_data = NULL; - tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1; - new_data = (ev_uint32_t*) realloc(msg->how_often_data, - tobe_allocated * sizeof(ev_uint32_t)); - if (new_data == NULL) - return -1; - msg->how_often_data = new_data; - msg->how_often_num_allocated = tobe_allocated; - return 0;} - -ev_uint32_t * -kill_how_often_add(struct kill *msg, const ev_uint32_t value) -{ - if (++msg->how_often_length >= msg->how_often_num_allocated) { - if (kill_how_often_expand_to_hold_more(msg)<0) - goto error; - } - msg->how_often_data[msg->how_often_length - 1] = value; - msg->how_often_set = 1; - return &(msg->how_often_data[msg->how_often_length - 1]); -error: - --msg->how_often_length; - return (NULL); -} - -int -kill_weapon_assign(struct kill *msg, - const char * value) -{ - if (msg->weapon_data != NULL) - free(msg->weapon_data); - if ((msg->weapon_data = strdup(value)) == NULL) - return (-1); - msg->weapon_set = 1; - return (0); -} - -int -kill_action_assign(struct kill *msg, - const char * value) -{ - if (msg->action_data != NULL) - free(msg->action_data); - if ((msg->action_data = strdup(value)) == NULL) - return (-1); - msg->action_set = 1; - return (0); -} - -int -kill_how_often_assign(struct kill *msg, int off, - const ev_uint32_t value) -{ - if (!msg->how_often_set || off < 0 || off >= msg->how_often_length) - return (-1); - - { - msg->how_often_data[off] = value; - } - return (0); -} - -int -kill_weapon_get(struct kill *msg, char * *value) -{ - if (msg->weapon_set != 1) - return (-1); - *value = msg->weapon_data; - return (0); -} - -int -kill_action_get(struct kill *msg, char * *value) -{ - if (msg->action_set != 1) - return (-1); - *value = msg->action_data; - return (0); -} - -int -kill_how_often_get(struct kill *msg, int offset, - ev_uint32_t *value) -{ - if (!msg->how_often_set || offset < 0 || offset >= msg->how_often_length) - return (-1); - *value = msg->how_often_data[offset]; - return (0); -} - -void -kill_clear(struct kill *tmp) -{ - if (tmp->weapon_set == 1) { - free(tmp->weapon_data); - tmp->weapon_data = NULL; - tmp->weapon_set = 0; - } - if (tmp->action_set == 1) { - free(tmp->action_data); - tmp->action_data = NULL; - tmp->action_set = 0; - } - if (tmp->how_often_set == 1) { - free(tmp->how_often_data); - tmp->how_often_data = NULL; - tmp->how_often_set = 0; - tmp->how_often_length = 0; - tmp->how_often_num_allocated = 0; - } -} - -void -kill_free(struct kill *tmp) -{ - if (tmp->weapon_data != NULL) - free (tmp->weapon_data); - if (tmp->action_data != NULL) - free (tmp->action_data); - if (tmp->how_often_set == 1) { - free(tmp->how_often_data); - tmp->how_often_data = NULL; - tmp->how_often_set = 0; - tmp->how_often_length = 0; - tmp->how_often_num_allocated = 0; - } - free(tmp->how_often_data); - free(tmp); -} - -void -kill_marshal(struct evbuffer *evbuf, const struct kill *tmp){ - evtag_marshal_string(evbuf, KILL_WEAPON, tmp->weapon_data); - evtag_marshal_string(evbuf, KILL_ACTION, tmp->action_data); - if (tmp->how_often_set) { - { - int i; - for (i = 0; i < tmp->how_often_length; ++i) { - evtag_marshal_int(evbuf, KILL_HOW_OFTEN, tmp->how_often_data[i]); - } - } - } -} - -int -kill_unmarshal(struct kill *tmp, struct evbuffer *evbuf) -{ - ev_uint32_t tag; - while (evbuffer_get_length(evbuf) > 0) { - if (evtag_peek(evbuf, &tag) == -1) - return (-1); - switch (tag) { - - case KILL_WEAPON: - - if (tmp->weapon_set) - return (-1); - if (evtag_unmarshal_string(evbuf, KILL_WEAPON, &tmp->weapon_data) == -1) { - event_warnx("%s: failed to unmarshal weapon", __func__); - return (-1); - } - tmp->weapon_set = 1; - break; - - case KILL_ACTION: - - if (tmp->action_set) - return (-1); - if (evtag_unmarshal_string(evbuf, KILL_ACTION, &tmp->action_data) == -1) { - event_warnx("%s: failed to unmarshal action", __func__); - return (-1); - } - tmp->action_set = 1; - break; - - case KILL_HOW_OFTEN: - - if (tmp->how_often_length >= tmp->how_often_num_allocated && - kill_how_often_expand_to_hold_more(tmp) < 0) { - puts("HEY NOW"); - return (-1); - } - if (evtag_unmarshal_int(evbuf, KILL_HOW_OFTEN, &tmp->how_often_data[tmp->how_often_length]) == -1) { - event_warnx("%s: failed to unmarshal how_often", __func__); - return (-1); - } - ++tmp->how_often_length; - tmp->how_often_set = 1; - break; - - default: - return -1; - } - } - - if (kill_complete(tmp) == -1) - return (-1); - return (0); -} - -int -kill_complete(struct kill *msg) -{ - if (!msg->weapon_set) - return (-1); - if (!msg->action_set) - return (-1); - return (0); -} - -int -evtag_unmarshal_kill(struct evbuffer *evbuf, ev_uint32_t need_tag, struct kill *msg) -{ - ev_uint32_t tag; - int res = -1; - - struct evbuffer *tmp = evbuffer_new(); - - if (evtag_unmarshal(evbuf, &tag, tmp) == -1 || tag != need_tag) - goto error; - - if (kill_unmarshal(msg, tmp) == -1) - goto error; - - res = 0; - - error: - evbuffer_free(tmp); - return (res); -} - -void -evtag_marshal_kill(struct evbuffer *evbuf, ev_uint32_t tag, const struct kill *msg) -{ - struct evbuffer *_buf = evbuffer_new(); - assert(_buf != NULL); - kill_marshal(_buf, msg); - evtag_marshal_buffer(evbuf, tag, _buf); - evbuffer_free(_buf); -} - -/* - * Implementation of run - */ - -static struct run_access_ __run_base = { - run_how_assign, - run_how_get, - run_some_bytes_assign, - run_some_bytes_get, - run_fixed_bytes_assign, - run_fixed_bytes_get, - run_notes_assign, - run_notes_get, - run_notes_add, - run_large_number_assign, - run_large_number_get, - run_other_numbers_assign, - run_other_numbers_get, - run_other_numbers_add, -}; - -struct run * -run_new(void) -{ - return run_new_with_arg(NULL); -} - -struct run * -run_new_with_arg(void *unused) -{ - struct run *tmp; - if ((tmp = malloc(sizeof(struct run))) == NULL) { - event_warn("%s: malloc", __func__); - return (NULL); - } - tmp->base = &__run_base; - - tmp->how_data = NULL; - tmp->how_set = 0; - - tmp->some_bytes_data = NULL; - tmp->some_bytes_length = 0; - tmp->some_bytes_set = 0; - - memset(tmp->fixed_bytes_data, 0, sizeof(tmp->fixed_bytes_data)); - tmp->fixed_bytes_set = 0; - - tmp->notes_data = NULL; - tmp->notes_length = 0; - tmp->notes_num_allocated = 0; - tmp->notes_set = 0; - - tmp->large_number_data = 0; - tmp->large_number_set = 0; - - tmp->other_numbers_data = NULL; - tmp->other_numbers_length = 0; - tmp->other_numbers_num_allocated = 0; - tmp->other_numbers_set = 0; - - return (tmp); -} - - - - -static int -run_notes_expand_to_hold_more(struct run *msg) -{ - int tobe_allocated = msg->notes_num_allocated; - char ** new_data = NULL; - tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1; - new_data = (char **) realloc(msg->notes_data, - tobe_allocated * sizeof(char *)); - if (new_data == NULL) - return -1; - msg->notes_data = new_data; - msg->notes_num_allocated = tobe_allocated; - return 0;} - -char * * -run_notes_add(struct run *msg, const char * value) -{ - if (++msg->notes_length >= msg->notes_num_allocated) { - if (run_notes_expand_to_hold_more(msg)<0) - goto error; - } - if (value != NULL) { - msg->notes_data[msg->notes_length - 1] = strdup(value); - if (msg->notes_data[msg->notes_length - 1] == NULL) { - goto error; - } - } else { - msg->notes_data[msg->notes_length - 1] = NULL; - } - msg->notes_set = 1; - return &(msg->notes_data[msg->notes_length - 1]); -error: - --msg->notes_length; - return (NULL); -} - - -static int -run_other_numbers_expand_to_hold_more(struct run *msg) -{ - int tobe_allocated = msg->other_numbers_num_allocated; - ev_uint32_t* new_data = NULL; - tobe_allocated = !tobe_allocated ? 1 : tobe_allocated << 1; - new_data = (ev_uint32_t*) realloc(msg->other_numbers_data, - tobe_allocated * sizeof(ev_uint32_t)); - if (new_data == NULL) - return -1; - msg->other_numbers_data = new_data; - msg->other_numbers_num_allocated = tobe_allocated; - return 0;} - -ev_uint32_t * -run_other_numbers_add(struct run *msg, const ev_uint32_t value) -{ - if (++msg->other_numbers_length >= msg->other_numbers_num_allocated) { - if (run_other_numbers_expand_to_hold_more(msg)<0) - goto error; - } - msg->other_numbers_data[msg->other_numbers_length - 1] = value; - msg->other_numbers_set = 1; - return &(msg->other_numbers_data[msg->other_numbers_length - 1]); -error: - --msg->other_numbers_length; - return (NULL); -} - -int -run_how_assign(struct run *msg, - const char * value) -{ - if (msg->how_data != NULL) - free(msg->how_data); - if ((msg->how_data = strdup(value)) == NULL) - return (-1); - msg->how_set = 1; - return (0); -} - -int -run_some_bytes_assign(struct run *msg, const ev_uint8_t * value, ev_uint32_t len) -{ - if (msg->some_bytes_data != NULL) - free (msg->some_bytes_data); - msg->some_bytes_data = malloc(len); - if (msg->some_bytes_data == NULL) - return (-1); - msg->some_bytes_set = 1; - msg->some_bytes_length = len; - memcpy(msg->some_bytes_data, value, len); - return (0); -} - -int -run_fixed_bytes_assign(struct run *msg, const ev_uint8_t *value) -{ - msg->fixed_bytes_set = 1; - memcpy(msg->fixed_bytes_data, value, 24); - return (0); -} - -int -run_notes_assign(struct run *msg, int off, - const char * value) -{ - if (!msg->notes_set || off < 0 || off >= msg->notes_length) - return (-1); - - { - if (msg->notes_data[off] != NULL) - free(msg->notes_data[off]); - msg->notes_data[off] = strdup(value); - if (msg->notes_data[off] == NULL) { - event_warnx("%s: strdup", __func__); - return (-1); - } - } - return (0); -} - -int -run_large_number_assign(struct run *msg, const ev_uint64_t value) -{ - msg->large_number_set = 1; - msg->large_number_data = value; - return (0); -} - -int -run_other_numbers_assign(struct run *msg, int off, - const ev_uint32_t value) -{ - if (!msg->other_numbers_set || off < 0 || off >= msg->other_numbers_length) - return (-1); - - { - msg->other_numbers_data[off] = value; - } - return (0); -} - -int -run_how_get(struct run *msg, char * *value) -{ - if (msg->how_set != 1) - return (-1); - *value = msg->how_data; - return (0); -} - -int -run_some_bytes_get(struct run *msg, ev_uint8_t * *value, ev_uint32_t *plen) -{ - if (msg->some_bytes_set != 1) - return (-1); - *value = msg->some_bytes_data; - *plen = msg->some_bytes_length; - return (0); -} - -int -run_fixed_bytes_get(struct run *msg, ev_uint8_t **value) -{ - if (msg->fixed_bytes_set != 1) - return (-1); - *value = msg->fixed_bytes_data; - return (0); -} - -int -run_notes_get(struct run *msg, int offset, - char * *value) -{ - if (!msg->notes_set || offset < 0 || offset >= msg->notes_length) - return (-1); - *value = msg->notes_data[offset]; - return (0); -} - -int -run_large_number_get(struct run *msg, ev_uint64_t *value) -{ - if (msg->large_number_set != 1) - return (-1); - *value = msg->large_number_data; - return (0); -} - -int -run_other_numbers_get(struct run *msg, int offset, - ev_uint32_t *value) -{ - if (!msg->other_numbers_set || offset < 0 || offset >= msg->other_numbers_length) - return (-1); - *value = msg->other_numbers_data[offset]; - return (0); -} - -void -run_clear(struct run *tmp) -{ - if (tmp->how_set == 1) { - free(tmp->how_data); - tmp->how_data = NULL; - tmp->how_set = 0; - } - if (tmp->some_bytes_set == 1) { - free (tmp->some_bytes_data); - tmp->some_bytes_data = NULL; - tmp->some_bytes_length = 0; - tmp->some_bytes_set = 0; - } - tmp->fixed_bytes_set = 0; - memset(tmp->fixed_bytes_data, 0, sizeof(tmp->fixed_bytes_data)); - if (tmp->notes_set == 1) { - int i; - for (i = 0; i < tmp->notes_length; ++i) { - if (tmp->notes_data[i] != NULL) free(tmp->notes_data[i]); - } - free(tmp->notes_data); - tmp->notes_data = NULL; - tmp->notes_set = 0; - tmp->notes_length = 0; - tmp->notes_num_allocated = 0; - } - tmp->large_number_set = 0; - if (tmp->other_numbers_set == 1) { - free(tmp->other_numbers_data); - tmp->other_numbers_data = NULL; - tmp->other_numbers_set = 0; - tmp->other_numbers_length = 0; - tmp->other_numbers_num_allocated = 0; - } -} - -void -run_free(struct run *tmp) -{ - if (tmp->how_data != NULL) - free (tmp->how_data); - if (tmp->some_bytes_data != NULL) - free(tmp->some_bytes_data); - if (tmp->notes_set == 1) { - int i; - for (i = 0; i < tmp->notes_length; ++i) { - if (tmp->notes_data[i] != NULL) free(tmp->notes_data[i]); - } - free(tmp->notes_data); - tmp->notes_data = NULL; - tmp->notes_set = 0; - tmp->notes_length = 0; - tmp->notes_num_allocated = 0; - } - free(tmp->notes_data); - if (tmp->other_numbers_set == 1) { - free(tmp->other_numbers_data); - tmp->other_numbers_data = NULL; - tmp->other_numbers_set = 0; - tmp->other_numbers_length = 0; - tmp->other_numbers_num_allocated = 0; - } - free(tmp->other_numbers_data); - free(tmp); -} - -void -run_marshal(struct evbuffer *evbuf, const struct run *tmp){ - evtag_marshal_string(evbuf, RUN_HOW, tmp->how_data); - if (tmp->some_bytes_set) { - evtag_marshal(evbuf, RUN_SOME_BYTES, tmp->some_bytes_data, tmp->some_bytes_length); - } - evtag_marshal(evbuf, RUN_FIXED_BYTES, tmp->fixed_bytes_data, (24)); - if (tmp->notes_set) { - { - int i; - for (i = 0; i < tmp->notes_length; ++i) { - evtag_marshal_string(evbuf, RUN_NOTES, tmp->notes_data[i]); - } - } - } - if (tmp->large_number_set) { - evtag_marshal_int64(evbuf, RUN_LARGE_NUMBER, tmp->large_number_data); - } - if (tmp->other_numbers_set) { - { - int i; - for (i = 0; i < tmp->other_numbers_length; ++i) { - evtag_marshal_int(evbuf, RUN_OTHER_NUMBERS, tmp->other_numbers_data[i]); - } - } - } -} - -int -run_unmarshal(struct run *tmp, struct evbuffer *evbuf) -{ - ev_uint32_t tag; - while (evbuffer_get_length(evbuf) > 0) { - if (evtag_peek(evbuf, &tag) == -1) - return (-1); - switch (tag) { - - case RUN_HOW: - - if (tmp->how_set) - return (-1); - if (evtag_unmarshal_string(evbuf, RUN_HOW, &tmp->how_data) == -1) { - event_warnx("%s: failed to unmarshal how", __func__); - return (-1); - } - tmp->how_set = 1; - break; - - case RUN_SOME_BYTES: - - if (tmp->some_bytes_set) - return (-1); - if (evtag_payload_length(evbuf, &tmp->some_bytes_length) == -1) - return (-1); - if (tmp->some_bytes_length > evbuffer_get_length(evbuf)) - return (-1); - if ((tmp->some_bytes_data = malloc(tmp->some_bytes_length)) == NULL) - return (-1); - if (evtag_unmarshal_fixed(evbuf, RUN_SOME_BYTES, tmp->some_bytes_data, tmp->some_bytes_length) == -1) { - event_warnx("%s: failed to unmarshal some_bytes", __func__); - return (-1); - } - tmp->some_bytes_set = 1; - break; - - case RUN_FIXED_BYTES: - - if (tmp->fixed_bytes_set) - return (-1); - if (evtag_unmarshal_fixed(evbuf, RUN_FIXED_BYTES, tmp->fixed_bytes_data, (24)) == -1) { - event_warnx("%s: failed to unmarshal fixed_bytes", __func__); - return (-1); - } - tmp->fixed_bytes_set = 1; - break; - - case RUN_NOTES: - - if (tmp->notes_length >= tmp->notes_num_allocated && - run_notes_expand_to_hold_more(tmp) < 0) { - puts("HEY NOW"); - return (-1); - } - if (evtag_unmarshal_string(evbuf, RUN_NOTES, &tmp->notes_data[tmp->notes_length]) == -1) { - event_warnx("%s: failed to unmarshal notes", __func__); - return (-1); - } - ++tmp->notes_length; - tmp->notes_set = 1; - break; - - case RUN_LARGE_NUMBER: - - if (tmp->large_number_set) - return (-1); - if (evtag_unmarshal_int64(evbuf, RUN_LARGE_NUMBER, &tmp->large_number_data) == -1) { - event_warnx("%s: failed to unmarshal large_number", __func__); - return (-1); - } - tmp->large_number_set = 1; - break; - - case RUN_OTHER_NUMBERS: - - if (tmp->other_numbers_length >= tmp->other_numbers_num_allocated && - run_other_numbers_expand_to_hold_more(tmp) < 0) { - puts("HEY NOW"); - return (-1); - } - if (evtag_unmarshal_int(evbuf, RUN_OTHER_NUMBERS, &tmp->other_numbers_data[tmp->other_numbers_length]) == -1) { - event_warnx("%s: failed to unmarshal other_numbers", __func__); - return (-1); - } - ++tmp->other_numbers_length; - tmp->other_numbers_set = 1; - break; - - default: - return -1; - } - } - - if (run_complete(tmp) == -1) - return (-1); - return (0); -} - -int -run_complete(struct run *msg) -{ - if (!msg->how_set) - return (-1); - if (!msg->fixed_bytes_set) - return (-1); - return (0); -} - -int -evtag_unmarshal_run(struct evbuffer *evbuf, ev_uint32_t need_tag, struct run *msg) -{ - ev_uint32_t tag; - int res = -1; - - struct evbuffer *tmp = evbuffer_new(); - - if (evtag_unmarshal(evbuf, &tag, tmp) == -1 || tag != need_tag) - goto error; - - if (run_unmarshal(msg, tmp) == -1) - goto error; - - res = 0; - - error: - evbuffer_free(tmp); - return (res); -} - -void -evtag_marshal_run(struct evbuffer *evbuf, ev_uint32_t tag, const struct run *msg) -{ - struct evbuffer *_buf = evbuffer_new(); - assert(_buf != NULL); - run_marshal(_buf, msg); - evtag_marshal_buffer(evbuf, tag, _buf); - evbuffer_free(_buf); -} - diff --git a/sntp/libevent/test/regress.gen.h b/sntp/libevent/test/regress.gen.h deleted file mode 100644 index 679558efd..000000000 --- a/sntp/libevent/test/regress.gen.h +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Automatically generated from ../../../../../sntp/build-libevent/../libevent/test/regress.rpc - */ - -#ifndef ________________SNTP_BUILD_LIBEVENT____LIBEVENT_TEST_REGRESS_RPC_ -#define ________________SNTP_BUILD_LIBEVENT____LIBEVENT_TEST_REGRESS_RPC_ - -#include /* for ev_uint*_t */ -#include - -struct msg; -struct kill; -struct run; - -/* Tag definition for msg */ -enum msg_ { - MSG_FROM_NAME=1, - MSG_TO_NAME=2, - MSG_ATTACK=3, - MSG_RUN=4, - MSG_MAX_TAGS -}; - -/* Structure declaration for msg */ -struct msg_access_ { - int (*from_name_assign)(struct msg *, const char *); - int (*from_name_get)(struct msg *, char * *); - int (*to_name_assign)(struct msg *, const char *); - int (*to_name_get)(struct msg *, char * *); - int (*attack_assign)(struct msg *, const struct kill*); - int (*attack_get)(struct msg *, struct kill* *); - int (*run_assign)(struct msg *, int, const struct run*); - int (*run_get)(struct msg *, int, struct run* *); - struct run* (*run_add)(struct msg *msg); -}; - -struct msg { - struct msg_access_ *base; - - char *from_name_data; - char *to_name_data; - struct kill* attack_data; - struct run* *run_data; - int run_length; - int run_num_allocated; - - ev_uint8_t from_name_set; - ev_uint8_t to_name_set; - ev_uint8_t attack_set; - ev_uint8_t run_set; -}; - -struct msg *msg_new(void); -struct msg *msg_new_with_arg(void *); -void msg_free(struct msg *); -void msg_clear(struct msg *); -void msg_marshal(struct evbuffer *, const struct msg *); -int msg_unmarshal(struct msg *, struct evbuffer *); -int msg_complete(struct msg *); -void evtag_marshal_msg(struct evbuffer *, ev_uint32_t, - const struct msg *); -int evtag_unmarshal_msg(struct evbuffer *, ev_uint32_t, - struct msg *); -int msg_from_name_assign(struct msg *, const char *); -int msg_from_name_get(struct msg *, char * *); -int msg_to_name_assign(struct msg *, const char *); -int msg_to_name_get(struct msg *, char * *); -int msg_attack_assign(struct msg *, const struct kill*); -int msg_attack_get(struct msg *, struct kill* *); -int msg_run_assign(struct msg *, int, const struct run*); -int msg_run_get(struct msg *, int, struct run* *); -struct run* msg_run_add(struct msg *msg); -/* --- msg done --- */ - -/* Tag definition for kill */ -enum kill_ { - KILL_WEAPON=65825, - KILL_ACTION=2, - KILL_HOW_OFTEN=3, - KILL_MAX_TAGS -}; - -/* Structure declaration for kill */ -struct kill_access_ { - int (*weapon_assign)(struct kill *, const char *); - int (*weapon_get)(struct kill *, char * *); - int (*action_assign)(struct kill *, const char *); - int (*action_get)(struct kill *, char * *); - int (*how_often_assign)(struct kill *, int, const ev_uint32_t); - int (*how_often_get)(struct kill *, int, ev_uint32_t *); - ev_uint32_t * (*how_often_add)(struct kill *msg, const ev_uint32_t value); -}; - -struct kill { - struct kill_access_ *base; - - char *weapon_data; - char *action_data; - ev_uint32_t *how_often_data; - int how_often_length; - int how_often_num_allocated; - - ev_uint8_t weapon_set; - ev_uint8_t action_set; - ev_uint8_t how_often_set; -}; - -struct kill *kill_new(void); -struct kill *kill_new_with_arg(void *); -void kill_free(struct kill *); -void kill_clear(struct kill *); -void kill_marshal(struct evbuffer *, const struct kill *); -int kill_unmarshal(struct kill *, struct evbuffer *); -int kill_complete(struct kill *); -void evtag_marshal_kill(struct evbuffer *, ev_uint32_t, - const struct kill *); -int evtag_unmarshal_kill(struct evbuffer *, ev_uint32_t, - struct kill *); -int kill_weapon_assign(struct kill *, const char *); -int kill_weapon_get(struct kill *, char * *); -int kill_action_assign(struct kill *, const char *); -int kill_action_get(struct kill *, char * *); -int kill_how_often_assign(struct kill *, int, const ev_uint32_t); -int kill_how_often_get(struct kill *, int, ev_uint32_t *); -ev_uint32_t * kill_how_often_add(struct kill *msg, const ev_uint32_t value); -/* --- kill done --- */ - -/* Tag definition for run */ -enum run_ { - RUN_HOW=1, - RUN_SOME_BYTES=2, - RUN_FIXED_BYTES=3, - RUN_NOTES=4, - RUN_LARGE_NUMBER=5, - RUN_OTHER_NUMBERS=6, - RUN_MAX_TAGS -}; - -/* Structure declaration for run */ -struct run_access_ { - int (*how_assign)(struct run *, const char *); - int (*how_get)(struct run *, char * *); - int (*some_bytes_assign)(struct run *, const ev_uint8_t *, ev_uint32_t); - int (*some_bytes_get)(struct run *, ev_uint8_t * *, ev_uint32_t *); - int (*fixed_bytes_assign)(struct run *, const ev_uint8_t *); - int (*fixed_bytes_get)(struct run *, ev_uint8_t **); - int (*notes_assign)(struct run *, int, const char *); - int (*notes_get)(struct run *, int, char * *); - char * * (*notes_add)(struct run *msg, const char * value); - int (*large_number_assign)(struct run *, const ev_uint64_t); - int (*large_number_get)(struct run *, ev_uint64_t *); - int (*other_numbers_assign)(struct run *, int, const ev_uint32_t); - int (*other_numbers_get)(struct run *, int, ev_uint32_t *); - ev_uint32_t * (*other_numbers_add)(struct run *msg, const ev_uint32_t value); -}; - -struct run { - struct run_access_ *base; - - char *how_data; - ev_uint8_t *some_bytes_data; - ev_uint32_t some_bytes_length; - ev_uint8_t fixed_bytes_data[24]; - char * *notes_data; - int notes_length; - int notes_num_allocated; - ev_uint64_t large_number_data; - ev_uint32_t *other_numbers_data; - int other_numbers_length; - int other_numbers_num_allocated; - - ev_uint8_t how_set; - ev_uint8_t some_bytes_set; - ev_uint8_t fixed_bytes_set; - ev_uint8_t notes_set; - ev_uint8_t large_number_set; - ev_uint8_t other_numbers_set; -}; - -struct run *run_new(void); -struct run *run_new_with_arg(void *); -void run_free(struct run *); -void run_clear(struct run *); -void run_marshal(struct evbuffer *, const struct run *); -int run_unmarshal(struct run *, struct evbuffer *); -int run_complete(struct run *); -void evtag_marshal_run(struct evbuffer *, ev_uint32_t, - const struct run *); -int evtag_unmarshal_run(struct evbuffer *, ev_uint32_t, - struct run *); -int run_how_assign(struct run *, const char *); -int run_how_get(struct run *, char * *); -int run_some_bytes_assign(struct run *, const ev_uint8_t *, ev_uint32_t); -int run_some_bytes_get(struct run *, ev_uint8_t * *, ev_uint32_t *); -int run_fixed_bytes_assign(struct run *, const ev_uint8_t *); -int run_fixed_bytes_get(struct run *, ev_uint8_t **); -int run_notes_assign(struct run *, int, const char *); -int run_notes_get(struct run *, int, char * *); -char * * run_notes_add(struct run *msg, const char * value); -int run_large_number_assign(struct run *, const ev_uint64_t); -int run_large_number_get(struct run *, ev_uint64_t *); -int run_other_numbers_assign(struct run *, int, const ev_uint32_t); -int run_other_numbers_get(struct run *, int, ev_uint32_t *); -ev_uint32_t * run_other_numbers_add(struct run *msg, const ev_uint32_t value); -/* --- run done --- */ - -#endif /* ________________SNTP_BUILD_LIBEVENT____LIBEVENT_TEST_REGRESS_RPC_ */ diff --git a/sntp/libevent/test/regress_dns.c b/sntp/libevent/test/regress_dns.c index 255f613a9..086fd4291 100644 --- a/sntp/libevent/test/regress_dns.c +++ b/sntp/libevent/test/regress_dns.c @@ -71,6 +71,8 @@ #include "regress.h" #include "regress_testutils.h" +#include "../util-internal.h" + static int dns_ok = 0; static int dns_got_cancel = 0; static int dns_err = 0; diff --git a/sntp/libevent/test/regress_http.c b/sntp/libevent/test/regress_http.c index 99e9f9389..4b894acc5 100644 --- a/sntp/libevent/test/regress_http.c +++ b/sntp/libevent/test/regress_http.c @@ -56,6 +56,7 @@ #include "event2/http.h" #include "event2/buffer.h" #include "event2/bufferevent.h" +#include "event2/util.h" #include "log-internal.h" #include "util-internal.h" #include "http-internal.h" @@ -128,38 +129,23 @@ static evutil_socket_t http_connect(const char *address, u_short port) { /* Stupid code for connecting */ -#ifdef WIN32 - struct hostent *he; - struct sockaddr_in sin; -#else - struct addrinfo ai, *aitop; + struct evutil_addrinfo ai, *aitop; char strport[NI_MAXSERV]; -#endif + struct sockaddr *sa; int slen; evutil_socket_t fd; -#ifdef WIN32 - if (!(he = gethostbyname(address))) { - event_warn("gethostbyname"); - } - memcpy(&sin.sin_addr, he->h_addr_list[0], he->h_length); - sin.sin_family = AF_INET; - sin.sin_port = htons(port); - slen = sizeof(struct sockaddr_in); - sa = (struct sockaddr*)&sin; -#else memset(&ai, 0, sizeof(ai)); ai.ai_family = AF_INET; ai.ai_socktype = SOCK_STREAM; evutil_snprintf(strport, sizeof(strport), "%d", port); - if (getaddrinfo(address, strport, &ai, &aitop) != 0) { + if (evutil_getaddrinfo(address, strport, &ai, &aitop) != 0) { event_warn("getaddrinfo"); return (-1); } sa = aitop->ai_addr; slen = aitop->ai_addrlen; -#endif fd = socket(AF_INET, SOCK_STREAM, 0); if (fd == -1) @@ -178,9 +164,7 @@ http_connect(const char *address, u_short port) #endif } -#ifndef WIN32 - freeaddrinfo(aitop); -#endif + evutil_freeaddrinfo(aitop); return (fd); } diff --git a/sntp/libevent/test/regress_listener.c b/sntp/libevent/test/regress_listener.c index 1438f3aa9..44fee7f4c 100644 --- a/sntp/libevent/test/regress_listener.c +++ b/sntp/libevent/test/regress_listener.c @@ -34,6 +34,9 @@ #ifndef WIN32 #include #include +# ifdef _XOPEN_SOURCE_EXTENDED +# include +# endif #include #endif diff --git a/sntp/libevent/test/regress_testutils.c b/sntp/libevent/test/regress_testutils.c index b5bef1abd..8902e6318 100644 --- a/sntp/libevent/test/regress_testutils.c +++ b/sntp/libevent/test/regress_testutils.c @@ -68,6 +68,8 @@ #include "regress.h" #include "regress_testutils.h" +#include "../util-internal.h" + /* globals */ static struct evdns_server_port *dns_port; evutil_socket_t dns_sock = -1; diff --git a/sntp/libevent/test/test-eof.c b/sntp/libevent/test/test-eof.c index 90b40938a..417476e80 100644 --- a/sntp/libevent/test/test-eof.c +++ b/sntp/libevent/test/test-eof.c @@ -32,6 +32,7 @@ int test_okay = 1; int called = 0; +struct timeval timeout = {60, 0}; static void read_cb(evutil_socket_t fd, short event, void *arg) @@ -39,6 +40,11 @@ read_cb(evutil_socket_t fd, short event, void *arg) char buf[256]; int len; + if (EV_TIMEOUT & event) { + printf("%s: Timeout!\n", __func__); + exit(1); + } + len = recv(fd, buf, sizeof(buf), 0); printf("%s: read %d%s\n", __func__, @@ -46,7 +52,7 @@ read_cb(evutil_socket_t fd, short event, void *arg) if (len) { if (!called) - event_add(arg, NULL); + event_add(arg, &timeout); } else if (called == 1) test_okay = 0; @@ -85,9 +91,9 @@ main(int argc, char **argv) event_init(); /* Initalize one event */ - event_set(&ev, pair[1], EV_READ, read_cb, &ev); + event_set(&ev, pair[1], EV_READ | EV_TIMEOUT, read_cb, &ev); - event_add(&ev, NULL); + event_add(&ev, &timeout); event_dispatch(); diff --git a/sntp/libevent/test/test-ratelim.c b/sntp/libevent/test/test-ratelim.c index 824434e08..bbbd76080 100644 --- a/sntp/libevent/test/test-ratelim.c +++ b/sntp/libevent/test/test-ratelim.c @@ -36,6 +36,9 @@ #else #include #include +# ifdef _XOPEN_SOURCE_EXTENDED +# include +# endif #endif #include @@ -46,6 +49,8 @@ #include "event2/listener.h" #include "event2/thread.h" +#include "../util-internal.h" + static int cfg_verbose = 0; static int cfg_help = 0; diff --git a/sntp/libevent/test/test.sh b/sntp/libevent/test/test.sh index 48deb9b1f..bca3da833 100755 --- a/sntp/libevent/test/test.sh +++ b/sntp/libevent/test/test.sh @@ -8,11 +8,16 @@ then fi # /bin/echo is a little more likely to support -n than sh's builtin echo. -if test -x /bin/echo +if test "`printf hello 2>&1`" = "hello" then - ECHO=/bin/echo + ECHO_N="printf" else - ECHO=echo + if test -x /bin/echo + then + ECHO_N="/bin/echo -n" + else + ECHO_N="echo -n" + fi fi if test "$TEST_OUTPUT_FILE" != "/dev/null" @@ -45,7 +50,7 @@ announce () { } announce_n () { - $ECHO -n "$@" + $ECHO_N "$@" echo "$@" >>"$TEST_OUTPUT_FILE" } @@ -91,6 +96,7 @@ run_tests () { announce FAILED ; FAILED=yes fi + test -x $TEST_DIR/regress || return announce_n " regress: " if test "$TEST_OUTPUT_FILE" = "/dev/null" ; then diff --git a/sntp/libevent/util-internal.h b/sntp/libevent/util-internal.h index cb76ee4fd..18d6ca75c 100644 --- a/sntp/libevent/util-internal.h +++ b/sntp/libevent/util-internal.h @@ -38,6 +38,8 @@ #endif #include "event2/util.h" +#include "ipv6-internal.h" + #ifdef __cplusplus extern "C" { #endif @@ -52,9 +54,13 @@ extern "C" { /* A good no-op to use in macro definitions. */ #define _EVUTIL_NIL_STMT ((void)0) -/* Suppresses the compiler's "unused variable" warnings for unused assert. */ +/* A no-op that tricks the compiler into thinking a condition is used while + * definitely not making any code for it. Used to compile out asserts while + * avoiding "unused variable" warnings. The "!" forces the compiler to + * do the sizeof() on an int, in case "condition" is a bitfield value. + */ #define _EVUTIL_NIL_CONDITION(condition) do { \ - (void)sizeof(condition); \ + (void)sizeof(!(condition)); \ } while(0) /* Internal use only: macros to match patterns of error codes in a @@ -201,6 +207,21 @@ long _evutil_weakrand(void); #define EVUTIL_FAILURE_CHECK(cond) EVUTIL_UNLIKELY(cond) #endif +#ifndef _EVENT_HAVE_STRUCT_SOCKADDR_STORAGE +/* Replacement for sockaddr storage that we can use internally on platforms + * that lack it. It is not space-efficient, but neither is sockaddr_storage. + */ +struct sockaddr_storage { + union { + struct sockaddr ss_sa; + struct sockaddr_in ss_sin; + struct sockaddr_in6 ss_sin6; + char ss_padding[128]; + } ss_union; +}; +#define ss_family ss_union.ss_sa.sa_family +#endif + /* Internal addrinfo error code. This one is returned from only from * evutil_getaddrinfo_common, when we are sure that we'll have to hit a DNS * server. */ diff --git a/sntp/log.c b/sntp/log.c index 8a524d203..8770b02bc 100644 --- a/sntp/log.c +++ b/sntp/log.c @@ -2,15 +2,17 @@ #include "log.h" -char *progname = "sntp"; /* for msyslog use too */ +char *progname; /* for msyslog use too */ static void cleanup_log(void); void -init_logging(void) +sntp_init_logging( + const char *prog + ) { - openlog(progname, LOG_PID | LOG_CONS, OPENLOG_FAC); msyslog_term = TRUE; + init_logging(prog, 0, NULL, FALSE); } @@ -19,13 +21,7 @@ open_logfile( const char *logfile ) { - syslog_file = fopen(logfile, "a"); - if (syslog_file == NULL) { - msyslog(LOG_ERR, "sntp: Cannot open logfile %s", - logfile); - return; - } - syslogit = FALSE; + change_logfile(logfile, Version); atexit(cleanup_log); } diff --git a/sntp/log.h b/sntp/log.h index b1878a023..fdb2ba21b 100644 --- a/sntp/log.h +++ b/sntp/log.h @@ -19,7 +19,9 @@ # define OPENLOG_FAC LOG_DAEMON #endif -void init_logging(void); +void sntp_init_logging(const char *program); void open_logfile(const char *logfile); +extern char *progname; /* for msyslog use too */ + #endif diff --git a/sntp/m4/ntp_bindir.m4 b/sntp/m4/ntp_bindir.m4 new file mode 100644 index 000000000..bddbe7efb --- /dev/null +++ b/sntp/m4/ntp_bindir.m4 @@ -0,0 +1,31 @@ +dnl ###################################################################### +dnl Installation binary directory. This may only apply to ntpd, not sntp +AC_DEFUN([NTP_BINDIR], [ + +AC_MSG_CHECKING([for bin subdirectory]) +AC_ARG_WITH( + [binsubdir], + [AS_HELP_STRING( + [--with-binsubdir], + [bin ={bin,sbin}] + )], + [use_binsubdir="$withval"], + [use_binsubdir="bin"] +) +case "$use_binsubdir" in + bin) + ;; + sbin) + ;; + *) + AC_MSG_ERROR([<$use_binsubdir> is illegal - must be "bin" or "sbin"]) + ;; +esac +AC_MSG_RESULT([$use_binsubdir]) + +BINSUBDIR=$use_binsubdir +AC_SUBST([BINSUBDIR]) +AM_CONDITIONAL([NTP_BINSUBDIR_IS_BIN], [test "bin" = "$BINSUBDIR"]) + +])dnl +dnl ====================================================================== diff --git a/sntp/m4/ntp_cacheversion.m4 b/sntp/m4/ntp_cacheversion.m4 index bf27b8913..3d943bc95 100644 --- a/sntp/m4/ntp_cacheversion.m4 +++ b/sntp/m4/ntp_cacheversion.m4 @@ -9,16 +9,18 @@ # all _cv_ variables only makes sense immediately after loading, before # use or modification. # -# It is assumed that parent configure.ac files which use -# AC_CONFIG_SUBDIR to invoke child configure.ac files have used -# NTP_CACHEVERSION if any children do. The top-level configure script +# The top-level configure.ac in a subtree using NTP_CACHEVERSION # will clear a previous cache lacking any saved cache version number, -# while children do not. The reason is the children can rely on the -# parent having cleared any cache variables predating this mechanism. -# Therefore the child can rely on the config.cache generated by the -# parent on the first run despite not finding its version stamp -# previously saved. In this case top-level means a configure script -# not invoked by another configure script in its parent directory. +# while children do not. This comes into play only when introducing +# NTP_CACHEVERSION where it had not been previously used: Previous +# cached results are presumed incompatible and not used. The reason +# children do not flush the cached is it is shared with the parent and +# the children can rely on the parent having cleared any cache variables +# predating this mechanism. Therefore the child can rely on the +# config.cache generated by the parent on the first run despite not +# finding the child version stamp in it. +# +# See html/copyright.html or COPYRIGHT in plain text. AC_DEFUN_ONCE([NTP_CACHEVERSION], [ AC_BEFORE([$0], [AM_INIT_AUTOMAKE])dnl diff --git a/sntp/m4/ntp_compiler.m4 b/sntp/m4/ntp_compiler.m4 new file mode 100644 index 000000000..7727d3f56 --- /dev/null +++ b/sntp/m4/ntp_compiler.m4 @@ -0,0 +1,124 @@ +dnl ###################################################################### +dnl Common m4sh code for compiler stuff +AC_DEFUN([NTP_COMPILER], [ +AC_REQUIRE([AC_PROG_CC_C89]) + +CFLAGS_NTP= +CPPFLAGS_NTP= +AC_SUBST([CFLAGS_NTP]) +AC_SUBST([CPPFLAGS_NTP]) + +case "$ac_cv_prog_cc_c89" in + no) + AC_MSG_WARN([ANSI C89/ISO C90 is the minimum to compile NTP] + [ version 4.2.5 and higher.]) + ;; +esac + +AC_CACHE_CHECK( + [if $CC can handle @%:@warning], + [ntp_cv_cpp_warning], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[#warning foo]])], + [ntp_cv_cpp_warning=yes], + [ntp_cv_cpp_warning=no] + )] +) +case "$ntp_cv_cpp_warning" in + no) + AC_DEFINE([NO_OPTION_NAME_WARNINGS], [1], + [Should we avoid @%:@warning on option name collisions?]) +esac + +case "$GCC" in + yes) + SAVED_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wstrict-overflow" + AC_CACHE_CHECK( + [if $CC can handle -Wstrict-overflow], + [ntp_cv_gcc_Wstrict_overflow], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [ntp_cv_gcc_Wstrict_overflow=yes], + [ntp_cv_gcc_Wstrict_overflow=no] + ) ] + ) + # + # $ntp_cv_gcc_Wstrict_overflow is tested later to add the + # flag to CFLAGS. + # + CFLAGS="$SAVED_CFLAGS -Winit-self" + AC_CACHE_CHECK( + [if $CC can handle -Winit-self], + [ntp_cv_gcc_Winit_self], + [ + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [ntp_cv_gcc_Winit_self=yes], + [ntp_cv_gcc_Winit_self=no] + ) + ] + ) + CFLAGS="$SAVED_CFLAGS" + AS_UNSET([SAVED_CFLAGS]) + # + # $ntp_cv_gcc_Winit_self is tested later to add the + # flag to CFLAGS_NTP. + # + AC_CACHE_CHECK( + [if linker supports omitting unused code and data], + [ntp_cv_gc_sections_works], + [ + origCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Wl,--gc-sections" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[]], [[]])], + [ + if grep gc-sections conftest.err ; then + ntp_cv_gc_sections_works=no + else + ntp_cv_gc_sections_works=yes + fi + ], + [ntp_cv_gc_sections_works=no] + ) + CFLAGS="$origCFLAGS" + AS_UNSET([origCFLAGS]) + ] + ) + case "$ntp_cv_gc_sections_works" in + yes) + LDADD_LIBNTP="-Wl,--gc-sections" + CFLAGS_NTP="$CFLAGS_NTP -ffunction-sections -fdata-sections" + ;; + no) + LDADD_LIBNTP= + ;; + esac + CFLAGS_NTP="$CFLAGS_NTP -Wall" + CFLAGS_NTP="$CFLAGS_NTP -Wcast-align" + CFLAGS_NTP="$CFLAGS_NTP -Wcast-qual" + # CFLAGS_NTP="$CFLAGS_NTP -Wconversion" + # CFLAGS_NTP="$CFLAGS_NTP -Werror" + # CFLAGS_NTP="$CFLAGS_NTP -Wextra" + # CFLAGS_NTP="$CFLAGS_NTP -Wfloat-equal" + CFLAGS_NTP="$CFLAGS_NTP -Wmissing-prototypes" + CFLAGS_NTP="$CFLAGS_NTP -Wpointer-arith" + CFLAGS_NTP="$CFLAGS_NTP -Wshadow" + # CFLAGS_NTP="$CFLAGS_NTP -Wtraditional" + # CFLAGS_NTP="$CFLAGS_NTP -Wwrite-strings" + case "$ntp_cv_gcc_Winit_self" in + yes) + CFLAGS_NTP="$CFLAGS_NTP -Winit-self" + esac + case "$ntp_cv_gcc_Wstrict_overflow" in + yes) + CFLAGS_NTP="$CFLAGS_NTP -Wstrict-overflow" + esac + # -W[no-]strict-prototypes might be added by NTP_OPENSSL +esac + +NTP_OS_CFLAGS + +])dnl +dnl ====================================================================== diff --git a/sntp/m4/ntp_crosscompile.m4 b/sntp/m4/ntp_crosscompile.m4 new file mode 100644 index 000000000..941618d39 --- /dev/null +++ b/sntp/m4/ntp_crosscompile.m4 @@ -0,0 +1,8 @@ +dnl ###################################################################### +AC_DEFUN([NTP_CROSSCOMPILE], [ + +# Expose a cross-compilation indicator to makefiles +AM_CONDITIONAL([NTP_CROSSCOMPILE], [test $build != $host]) + +])dnl +dnl ====================================================================== diff --git a/sntp/m4/ntp_debug.m4 b/sntp/m4/ntp_debug.m4 new file mode 100644 index 000000000..820f9a0bc --- /dev/null +++ b/sntp/m4/ntp_debug.m4 @@ -0,0 +1,22 @@ +dnl ###################################################################### +dnl Common m4sh code for debug +AC_DEFUN([NTP_DEBUG], [ + +AC_MSG_CHECKING([if we're including debugging code]) +AC_ARG_ENABLE( + [debugging], + [AS_HELP_STRING( + [--enable-debugging], + [+ include ntpd debugging code] + )], + [ntp_ok=$enableval], + [ntp_ok=yes] +) +case "$ntp_ok" in + yes) + AC_DEFINE([DEBUG], [1], [Enable debugging code?]) +esac +AC_MSG_RESULT([$ntp_ok]) + +])dnl +dnl ====================================================================== diff --git a/sntp/m4/ntp_ipv6.m4 b/sntp/m4/ntp_ipv6.m4 index 1c6f21eb2..ccb9bf735 100644 --- a/sntp/m4/ntp_ipv6.m4 +++ b/sntp/m4/ntp_ipv6.m4 @@ -2,7 +2,6 @@ dnl ###################################################################### dnl Common IPv6 detection for NTP configure.ac files AC_DEFUN([NTP_IPV6], [ - AC_CACHE_CHECK( [for struct sockaddr_storage], [ntp_cv_sockaddr_storage], @@ -31,36 +30,6 @@ case "$ntp_cv_sockaddr_storage" in yes) AC_DEFINE([HAVE_STRUCT_SOCKADDR_STORAGE], [1], [Does a system header define struct sockaddr_storage?]) -esac - -AC_CACHE_CHECK( - [for sockaddr_storage.ss_family], - [ntp_cv_have_ss_family], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #ifdef HAVE_SYS_TYPES_H - # include - #endif - #ifdef HAVE_SYS_SOCKET_H - # include - #endif - #ifdef HAVE_NETINET_IN_H - # include - #endif - ]], - [[ - struct sockaddr_storage s; - s.ss_family = 1; - ]] - )], - [ntp_cv_have_ss_family=yes], - [ntp_cv_have_ss_family=no] - )] -) - -case "$ntp_cv_have_ss_family" in - no) AC_CACHE_CHECK( [for sockaddr_storage.__ss_family], [ntp_cv_have___ss_family], @@ -89,91 +58,19 @@ case "$ntp_cv_have_ss_family" in case "$ntp_cv_have___ss_family" in yes) AC_DEFINE([HAVE___SS_FAMILY_IN_SS], [1], - [Does struct sockaddr_storage have __ss_family?]) + [Does struct sockaddr_storage have __ss_family?]) esac - ;; -esac - -AH_VERBATIM( - [HAVE___SS_FAMILY_IN_SS_VERBATIM], - [ - /* Handle sockaddr_storage.__ss_family */ - #ifdef HAVE___SS_FAMILY_IN_SS - # define ss_family __ss_family - #endif /* HAVE___SS_FAMILY_IN_SS */ - ] -) - -AC_CACHE_CHECK( - [for sockaddr_storage.ss_len], - [ntp_cv_have_ss_len], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #ifdef HAVE_SYS_TYPES_H - # include - #endif - #ifdef HAVE_SYS_SOCKET_H - # include - #endif - #ifdef HAVE_NETINET_IN_H - # include - #endif - ]], - [[ - struct sockaddr_storage s; - s.ss_len = 1; - ]] - )], - [ntp_cv_have_ss_len=yes], - [ntp_cv_have_ss_len=no] - )] -) - -case "$ntp_cv_have_ss_len" in - no) - AC_CACHE_CHECK( - [for sockaddr_storage.__ss_len], - [ntp_cv_have___ss_len], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM( - [[ - #ifdef HAVE_SYS_TYPES_H - # include - #endif - #ifdef HAVE_SYS_SOCKET_H - # include - #endif - #ifdef HAVE_NETINET_IN_H - # include - #endif - ]], - [[ - struct sockaddr_storage s; - s.__ss_len = 1; - ]] - )], - [ntp_cv_have___ss_len=yes], - [ntp_cv_have___ss_len=no] - )] + AH_VERBATIM( + [HAVE___SS_FAMILY_IN_SS_VERBATIM], + [ + /* Handle sockaddr_storage.__ss_family */ + #ifdef HAVE___SS_FAMILY_IN_SS + # define ss_family __ss_family + #endif /* HAVE___SS_FAMILY_IN_SS */ + ] ) - case "$ntp_cv_have___ss_len" in - yes) - AC_DEFINE([HAVE___SS_LEN_IN_SS], [1], - [Does struct sockaddr_storage have __ss_len?]) - esac - ;; esac -AH_VERBATIM( - [HAVE___SS_LEN_IN_SS_VERBATIM], - [ - /* Handle sockaddr_storage.__ss_len */ - #ifdef HAVE___SS_LEN_IN_SS - # define ss_len __ss_len - #endif /* HAVE___SS_LEN_IN_SS */ - ] -) # # Look for in_port_t. @@ -522,6 +419,124 @@ case "$isc_cv_struct_if_laddrreq" in [have struct if_laddrreq?]) esac +AC_CACHE_CHECK( + [for multicast IP support], + [ntp_cv_multicast], + [ + ntp_cv_multicast=no + case "$host" in + i386-sequent-sysv4) + ;; + *) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #ifdef HAVE_NETINET_IN_H + # include + #endif + ]], + [[ + struct ip_mreq ipmr; + ipmr.imr_interface.s_addr = 0; + ]] + )], + [ntp_cv_multicast=yes], + [] + ) + ;; + esac + ] +) +case "$ntp_cv_multicast" in + yes) + AC_DEFINE([MCAST], [1], [Does the target support multicast IP?]) + AC_CACHE_CHECK( + [arg type needed for setsockopt() IP*_MULTICAST_LOOP], + [ntp_cv_typeof_ip_multicast_loop], + [ + case "$host" in + *-*-netbsd*|*-*-*linux*) + ntp_cv_typeof_ip_multicast_loop=u_int + ;; + *) + ntp_cv_typeof_ip_multicast_loop=u_char + ;; + esac + ] + ) + AC_DEFINE_UNQUOTED([TYPEOF_IP_MULTICAST_LOOP], + [$ntp_cv_typeof_ip_multicast_loop], + [What type to use for setsockopt]) +esac + +AC_ARG_ENABLE( + [getifaddrs], + [AS_HELP_STRING( + [--enable-getifaddrs], + [s Enable the use of getifaddrs() [[yes|no|glibc]]. +glibc: Use getifaddrs() in glibc if you know it supports IPv6.] + )], + [want_getifaddrs="$enableval"], + [want_getifaddrs="yes"] +) + +case $want_getifaddrs in + yes|glibc) + # + # Do we have getifaddrs() ? + # + case $host in + *-*linux*) + # Some recent versions of glibc support getifaddrs() which does not + # provide AF_INET6 addresses while the function provided by the USAGI + # project handles the AF_INET6 case correctly. We need to avoid + # using the former but prefer the latter unless overridden by + # --enable-getifaddrs=glibc. + case "$want_getifaddrs" in + glibc) + AC_CHECK_FUNCS([getifaddrs]) + ;; + *) + save_LIBS="$LIBS" + LIBS="-L/usr/local/v6/lib $LIBS" + AC_CHECK_LIB( + [inet6], + [getifaddrs], + [ans=yes], + [ans=no] + ) + case "$ans" in + yes) + LIBS="$LIBS -linet6" + AC_DEFINE([HAVE_GETIFADDRS], [1]) + ;; + *) + LIBS=${save_LIBS} + ;; + esac + ;; + esac + ;; + esac + ;; + *) + AC_CHECK_FUNCS([getifaddrs]) + ;; +esac + +# +# Check for if_nametoindex() for IPv6 scoped addresses support +# +case "$host" in + *-hp-hpux*) + AC_SEARCH_LIBS([if_nametoindex], [ipv6]) +esac +AC_CHECK_FUNCS([if_nametoindex]) +case "$ac_cv_func_if_nametoindex" in + yes) + AC_DEFINE([ISC_PLATFORM_HAVEIFNAMETOINDEX], [1], + [ISC: do we have if_nametoindex()?]) +esac ])dnl dnl ====================================================================== diff --git a/sntp/m4/ntp_libevent.m4 b/sntp/m4/ntp_libevent.m4 index e8c270f59..35bc047e6 100644 --- a/sntp/m4/ntp_libevent.m4 +++ b/sntp/m4/ntp_libevent.m4 @@ -1,4 +1,4 @@ -dnl NTP_LIBEVENT_CHECK([MINVERSION, [DIR [, NOBUILD]]]) -*- Autoconf -*- +dnl NTP_LIBEVENT_CHECK_NOBUILD([MINVERSION [, DIR]]) -*- Autoconf -*- dnl dnl Look for libevent, which must be at least MINVERSION. dnl DIR is the location of our "bundled" copy of libevent. @@ -10,30 +10,24 @@ dnl provide --enable-local-libevent . dnl dnl Examples: dnl -dnl NTP_LIBEVENT_CHECK([2.0.9], [sntp/libevent], NOBUILD) +dnl NTP_LIBEVENT_CHECK_NOBUILD([2.0.9], [sntp/libevent]) dnl NTP_LIBEVENT_CHECK dnl +AC_DEFUN([NTP_LIBEVENT_CHECK_NOBUILD], [ -dnl -dnl NOTE WELL: right now, if we build the local libevent, the 'install' -dnl target *will fire* -dnl - -AC_DEFUN([NTP_LIBEVENT_CHECK], [ -_ntp_pkg_min_version=m4_default([$1], [0.9.0]) -_ntp_libevent_min_version=m4_default([$1], [2.0.9]) -_ntp_libevent_path=m4_default([$2], [libevent]) -_ntp_libevent_nobuild=m4_default([$3],[]) -_ntp_libevent_found=no +ntp_pkgconfig_min_version='0.15.0' +ntp_libevent_min_version=m4_default([$1], [2.0.9]) +ntp_libevent_tearoff=m4_default([$2], [libevent]) -NEED_LIBEVENT_DIR= +AC_SUBST([CPPFLAGS_LIBEVENT]) +AC_SUBST([LDADD_LIBEVENT]) AC_PATH_TOOL([PKG_CONFIG], [pkg-config]) # Make sure pkg-config is recent enough case "$PKG_CONFIG" in /*) - AC_MSG_CHECKING([pkg-config is at least version $_ntp_pkg_min_version]) - if $PKG_CONFIG --atleast-pkgconfig-version $_ntp_pkg_min_version; then + AC_MSG_CHECKING([if pkg-config is at least version $ntp_pkgconfig_min_version]) + if $PKG_CONFIG --atleast-pkgconfig-version $ntp_pkgconfig_min_version; then AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -42,39 +36,92 @@ case "$PKG_CONFIG" in ;; esac -AC_ARG_ENABLE([local-libevent], - AC_HELP_STRING([-enable-local-libevent], - [Force using the supplied libevent tearoff code]),[ - use_local_libevent=$enableval]) +AC_ARG_ENABLE( + [local-libevent], + [AC_HELP_STRING( + [--enable-local-libevent], + [Force using the supplied libevent tearoff code] + )], + [ntp_use_local_libevent=$enableval], + [ntp_use_local_libevent=${ntp_use_local_libevent-detect}] +) -case "$use_local_libevent" in +case "$ntp_use_local_libevent" in yes) ;; + no) + ;; *) # If we have (a good enough) pkg-config, see if it can find libevent case "$PKG_CONFIG" in /*) - if $PKG_CONFIG --atleast-version=$_ntp_libevent_min_version libevent + AC_MSG_CHECKING([if libevent 2.0.9 or later is installed]) + if $PKG_CONFIG --atleast-version=$ntp_libevent_min_version libevent then + ntp_use_local_libevent=no AC_MSG_NOTICE([Using the installed libevent]) - LIBEVENT_CPPFLAGS=`$PKG_CONFIG --cflags libevent` - LIBEVENT_LDADD=`$PKG_CONFIG --libs libevent` - _ntp_libevent_found=yes + CPPFLAGS_LIBEVENT=`$PKG_CONFIG --cflags-only-I libevent` + LDADD_LIBEVENT=`$PKG_CONFIG --libs-only-L libevent` + case "$LIBISC_PTHREADS_NOTHREADS" in + pthreads) + LDADD_LIBEVENT="$LDADD_LIBEVENT -levent_pthreads" + esac + LDADD_LIBEVENT="$LDADD_LIBEVENT -levent_core" + AC_MSG_RESULT([yes]) + else + ntp_use_local_libevent=yes + AC_MSG_RESULT([no]) fi ;; + *) + ntp_use_local_libevent=yes + ;; esac ;; esac -case "$_ntp_libevent_found" in - no) - AC_MSG_NOTICE([Using supplied libevent tearoff]) - LIBEVENT_CPPFLAGS='-I$(top_builddir)'/_il/include - LIBEVENT_LDADD='$(top_builddir)'/_il/lib/libevent.la - NEED_LIBEVENT_DIR=true +case "$ntp_use_local_libevent" in + yes) + AC_MSG_NOTICE([Using libevent tearoff]) + CPPFLAGS_LIBEVENT="-I\$(top_builddir)/$ntp_libevent_tearoff/include -I\$(top_srcdir)/$ntp_libevent_tearoff/include" + case "$LIBISC_PTHREADS_NOTHREADS" in + pthreads) + LDADD_LIBEVENT="\$(top_builddir)/$ntp_libevent_tearoff/libevent_pthreads.la \$(top_builddir)/$ntp_libevent_tearoff/libevent_core.la" + ;; + *) + LDADD_LIBEVENT="\$(top_builddir)/$ntp_libevent_tearoff/libevent_core.la" + esac +esac + +AM_CONDITIONAL([BUILD_LIBEVENT], [test "x$ntp_use_local_libevent" = "xyes"]) + +]) dnl NTP_LIBEVENT_CHECK_NOBUILD + +dnl NTP_LIBEVENT_CHECK([MINVERSION [, DIR]]) -*- Autoconf -*- +AC_DEFUN([NTP_LIBEVENT_CHECK], [ + +AC_SUBST([NTP_FORCE_LIBEVENT_DIST]) +NTP_LIBEVENT_CHECK_NOBUILD([$1], [$2]) + +case "$ntp_libevent_tearoff" in + libevent) + ;; + *) + AC_MSG_ERROR([ntp_libevent.m4 dir must be libevent, not $ntp_libevent_tearoff]) ;; esac -AM_CONDITIONAL([NEED_LIBEVENT], [test -n "${NEED_LIBEVENT_DIR}"]) -AC_SUBST(LIBEVENT_CPPFLAGS) -AC_SUBST(LIBEVENT_LDADD) -]) +case "$ntp_use_local_libevent" in + yes) + dnl ac_configure_args is undocumented but widely abused. + ac_configure_args="--disable-shared $ac_configure_args" + ac_configure_args="--disable-libevent-regress $ac_configure_args" + ac_configure_args="--disable-libevent-install $ac_configure_args" + AC_CONFIG_SUBDIRS([libevent]) + ;; + *) + NTP_FORCE_LIBEVENT_DIST=libevent + ;; +esac + +]) dnl NTP_LIBEVENT_CHECK + diff --git a/sntp/m4/ntp_libntp.m4 b/sntp/m4/ntp_libntp.m4 index 5a219d2ce..758ff6328 100644 --- a/sntp/m4/ntp_libntp.m4 +++ b/sntp/m4/ntp_libntp.m4 @@ -1,151 +1,44 @@ dnl ###################################################################### -dnl Common m4sh code for debug and libntp clients +dnl Common m4sh code for libntp and clients +dnl +dnl Any configure tests which libntp or libisc code depends upon should +dnl be here or in another m4 macro used by the top-level and sntp +dnl configure.ac files, so that libntp can be moved into the sntp +dnl subpackage while retaining access to such test results. +dnl AC_DEFUN([NTP_LIBNTP], [ -AC_MSG_CHECKING([if we're including debugging code]) -AC_ARG_ENABLE( - [debugging], - [AS_HELP_STRING( - [--enable-debugging], - [+ include ntpd debugging code] - )], - [ntp_ok=$enableval], - [ntp_ok=yes] -) -case "$ntp_ok" in - yes) - AC_DEFINE([DEBUG], [1], [Enable debugging code?]) -esac -AC_MSG_RESULT([$ntp_ok]) - -# Expose a cross-compilation indicator to makefiles -AM_CONDITIONAL([NTP_CROSSCOMPILE], [test $build != $host]) - -CFLAGS_NTP= -CPPFLAGS_NTP= -AC_SUBST([CFLAGS_NTP]) -AC_SUBST([CPPFLAGS_NTP]) - -# AC_PROG_CC_STDC has two functions. It attempts to find a compiler -# capable of C99, or failing that, for C89. CC is set afterward with -# the selected invocation, such as "gcc --std=gnu99". Also, the -# ac_cv_prog_cc_stdc variable is no if the compiler selected for CC -# does not accept C89. +AC_REQUIRE([NTP_DEBUG]) +AC_REQUIRE([NTP_CROSSCOMPILE]) -AC_PROG_CC_STDC +# HMS: Save $LIBS and empty it. +# any LIBS we add here should go in to LDADD_LIBNTP +AC_SUBST([LDADD_LIBNTP]) +__LIBS=$LIBS +LIBS= -case "$ac_cv_prog_cc_stdc" in - no) - AC_MSG_WARN([ANSI C89/ISO C90 is the minimum to compile NTP] - [ version 4.2.5 and higher.]) - ;; -esac - -AC_CACHE_CHECK( - [if $CC can handle @%:@warning], - [ntp_cv_cpp_warning], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], [[#warning foo]])], - [ntp_cv_cpp_warning=yes], - [ntp_cv_cpp_warning=no] - )] -) -case "$ntp_cv_cpp_warning" in - no) - AC_DEFINE([NO_OPTION_NAME_WARNINGS], [1], - [Should we avoid @%:@warning on option name collisions?]) -esac +dnl must come before AC_PROG_CC or similar +AC_USE_SYSTEM_EXTENSIONS -case "$GCC" in - yes) - SAVED_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -Wstrict-overflow" - AC_CACHE_CHECK( - [if $CC can handle -Wstrict-overflow], - [ntp_cv_gcc_Wstrict_overflow], - [AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], [[]])], - [ntp_cv_gcc_Wstrict_overflow=yes], - [ntp_cv_gcc_Wstrict_overflow=no] - ) ] - ) - # - # $ntp_cv_gcc_Wstrict_overflow is tested later to add the - # flag to CFLAGS. - # - CFLAGS="$SAVED_CFLAGS -Winit-self" - AC_CACHE_CHECK( - [if $CC can handle -Winit-self], - [ntp_cv_gcc_Winit_self], - [ - AC_COMPILE_IFELSE( - [AC_LANG_PROGRAM([[]], [[]])], - [ntp_cv_gcc_Winit_self=yes], - [ntp_cv_gcc_Winit_self=no] - ) - ] - ) - CFLAGS="$SAVED_CFLAGS" - AS_UNSET([SAVED_CFLAGS]) - # - # $ntp_cv_gcc_Winit_self is tested later to add the - # flag to CFLAGS_NTP. - # -esac +dnl we need to check for cross compile tools for vxWorks here +AC_PROG_CC +# Ralf Wildenhues: With per-target flags we need CC_C_O +# AM_PROG_CC_C_O supersets AC_PROG_CC_C_O +AM_PROG_CC_C_O +AC_PROG_GCC_TRADITIONAL +NTP_COMPILER +AC_C_BIGENDIAN +AC_C_VOLATILE +AC_PROG_CPP +AC_PROG_INSTALL -case "$GCC" in - yes) - CFLAGS_NTP="$CFLAGS_NTP -Wall" - # CFLAGS_NTP="$CFLAGS_NTP -Wcast-align" - CFLAGS_NTP="$CFLAGS_NTP -Wcast-qual" - # CFLAGS_NTP="$CFLAGS_NTP -Wconversion" - # CFLAGS_NTP="$CFLAGS_NTP -Werror" - # CFLAGS_NTP="$CFLAGS_NTP -Wextra" - # CFLAGS_NTP="$CFLAGS_NTP -Wfloat-equal" - CFLAGS_NTP="$CFLAGS_NTP -Wmissing-prototypes" - CFLAGS_NTP="$CFLAGS_NTP -Wpointer-arith" - CFLAGS_NTP="$CFLAGS_NTP -Wshadow" - # CFLAGS_NTP="$CFLAGS_NTP -Wtraditional" - # CFLAGS_NTP="$CFLAGS_NTP -Wwrite-strings" - case "$ntp_cv_gcc_Winit_self" in - yes) - CFLAGS_NTP="$CFLAGS_NTP -Winit-self" - esac - case "$ntp_cv_gcc_Wstrict_overflow" in - yes) - CFLAGS_NTP="$CFLAGS_NTP -Wstrict-overflow" - esac - # -W[no-]strict-prototypes might be added by NTP_OPENSSL -esac - -NTP_OS_CFLAGS -NTP_LIB_M +NTP_BINDIR NTP_DIR_SEP +NTP_LINEEDITLIBS +NTP_LIB_M -AC_MSG_CHECKING([for bin subdirectory]) -AC_ARG_WITH( - [binsubdir], - [AS_HELP_STRING( - [--with-binsubdir], - [bin ={bin,sbin}] - )], - [use_binsubdir="$withval"], - [use_binsubdir="bin"] -) -case "$use_binsubdir" in - bin) - ;; - sbin) - ;; - *) - AC_MSG_ERROR([<$use_binsubdir> is illegal - must be "bin" or "sbin"]) - ;; -esac -AC_MSG_RESULT([$use_binsubdir]) - -BINSUBDIR=$use_binsubdir -AC_SUBST([BINSUBDIR]) -AM_CONDITIONAL([NTP_BINSUBDIR_IS_BIN], [test "bin" = "$BINSUBDIR"]) +AC_FUNC_FORK +AC_FUNC_ALLOCA ac_busted_vpath_in_make=no case "$build" in @@ -173,6 +66,22 @@ case "$ac_busted_vpath_in_make$srcdir" in ;; esac +case "$host" in + *-*-aix[[456]]*) + # (prr) aix 4.1 doesn't have clock_settime, but in aix 4.3 it's a stub + # (returning ENOSYS). I didn't check 4.2. If, in the future, + # IBM pulls its thumbs out long enough to implement clock_settime, + # this conditional will need to change. Maybe use AC_TRY_RUN + # instead to try to set the time to itself and check errno. + ;; + *) + AC_SEARCH_LIBS([clock_gettime], [rt]) + AC_CHECK_FUNCS([clock_gettime clock_settime]) + ;; +esac + +AC_CHECK_FUNCS([getclock stime timegm]) + dnl HP-UX 11.31 on HPPA has a net/if.h that can't be compiled with gcc4 dnl due to an incomplete type (a union) mpinfou used in an array. gcc3 dnl compiles it without complaint. The mpinfou union is defined later @@ -184,7 +93,7 @@ dnl net/if.h. If that fails, try adding a duplicate definition of dnl mpinfou, and if that helps add it to confdefs.h (used for further dnl configure tests) and config.h. # -AC_CHECK_HEADERS([sys/socket.h]) +AC_CHECK_HEADERS([errno.h sys/socket.h sys/types.h]) AC_CHECK_HEADERS([net/if.h], [], [], [ #ifdef HAVE_SYS_SOCKET_H # include @@ -245,6 +154,67 @@ typedef union mpinfou { esac esac +AC_CHECK_HEADERS([arpa/nameser.h sys/param.h sys/time.h sys/timers.h]) +# sys/sysctl.h depends on sys/param.h on OpenBSD - Bug 1576 +AC_CHECK_HEADERS([sys/sysctl.h], [], [], [ + #if defined HAVE_SYS_PARAM_H + # include + #endif +]) +AC_CHECK_HEADERS([netinet/in_system.h netinet/in_systm.h netinet/in.h]) + +AC_CHECK_HEADERS([resolv.h], [], [], [ + #ifdef HAVE_SYS_TYPES_H + # include + #endif + #ifdef HAVE_NETINET_IN_H + # include + #endif + #ifdef HAVE_ARPA_NAMESER_H + # include + #endif +]) + +AC_CHECK_HEADERS([net/if_var.h], [], [], [ + #if HAVE_SYS_TYPES_H + # include + #endif + #ifdef HAVE_SYS_SOCKET_H + # include + #endif + #ifdef HAVE_NETINET_IN_H + # include + #endif + #ifdef HAVE_NET_IF_H + # include + #endif +]) + +AC_CHECK_HEADERS([netinet/ip.h netinet/in_var.h], [], [], [ + #ifdef HAVE_SYS_TYPES_H + # include + #endif + #ifdef HAVE_SYS_SOCKET_H + # include + #endif + #ifdef HAVE_NET_IF_H + # include + #endif + #ifdef HAVE_NETINET_IN_H + # include + #endif + #ifdef HAVE_NET_IF_VAR_H + # include + #endif + #ifdef HAVE_NETINET_IN_SYSTM_H + # include + #endif +]) + +# HMS: Do we need to check for -lsocket before or after these tests? +AC_SEARCH_LIBS([inet_pton], [nsl]) +AC_SEARCH_LIBS([inet_ntop], [resolv], , , [-lnsl]) + # [Bug 1628] On Solaris, we need -lxnet -lsocket. Generalize this to # avoid keying on the OS name: If we find socket functions in # libsocket, next try for them in libxnet without libsocket, if found, @@ -323,28 +293,655 @@ esac AC_TYPE_UID_T AC_FUNC_STRERROR_R -dnl preset withsntp=no in env to change default to --without-sntp -AC_MSG_CHECKING([if sntp will be built]) -AC_ARG_WITH( - [sntp], +# check if we can compile with pthreads +AC_CHECK_HEADERS([semaphore.h]) +AC_CHECK_FUNCS([sem_timedwait socketpair]) +AC_ARG_ENABLE( + [thread-support], + [AS_HELP_STRING([--disable-thread-support, do not use threads])], + [], + [enable_thread_support=yes] + ) +have_pthreads=no +case "$enable_thread_support:$ac_cv_func_sem_timedwait" in + yes:yes) + OL_THREAD_CHECK( + [ + have_pthreads=yes + PTHREAD_LIBS="$LTHREAD_LIBS" + ] + ) +esac +AC_SUBST([PTHREAD_LIBS]) +case "$have_pthreads" in + yes) + CFLAGS_NTP="$CFLAGS_NTP $PTHREAD_CFLAGS" + saved_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $PTHREAD_CFLAGS" + AC_CHECK_SIZEOF( + [pthread_t], + [], + [ + AC_INCLUDES_DEFAULT() + #include + ] + ) + LIBISC_PTHREADS_NOTHREADS=pthreads + AC_DEFINE([ISC_PLATFORM_USETHREADS], [1], + [enable libisc thread support?]) + # + # We'd like to use sigwait() too + # + AC_CHECK_FUNC( + [sigwait], + [have_sigwait=yes], + [AC_CHECK_LIB( + [c], + [sigwait], + [have_sigwait=yes], + [AC_CHECK_LIB( + [pthread], + [sigwait], + [have_sigwait=yes], + [AC_CHECK_LIB( + [pthread], + [_Psigwait], + [have_sigwait=yes], + [have_sigwait=no] + )] + )] + )] + ) + case "$host:$have_sigwait" in + *-freebsd*:no) + AC_CHECK_LIB( + [c_r], + [sigwait], + [have_sigwait=yes], + [] + ) + esac + case "$have_sigwait" in + yes) + ac_cv_func_sigwait=yes + AC_DEFINE([HAVE_SIGWAIT], [1], [sigwait() available?]) + esac + + AC_CHECK_FUNCS([pthread_attr_getstacksize]) + AC_CHECK_FUNCS([pthread_attr_setstacksize sysconf]) + + case "$host" in + *-freebsd5.[[012]]|*-freebsd5.[[012]].*) + ;; + *-freebsd5.[[3456789]]|*-freebsd5.[[3456789]].*|*-freebsd6.*) + AC_DEFINE([NEED_PTHREAD_SCOPE_SYSTEM], [1], + [use PTHREAD_SCOPE_SYSTEM?]) + ;; + *-bsdi3.*|*-bsdi4.0*) + AC_DEFINE([NEED_PTHREAD_INIT], [1], [pthread_init() required?]) + ;; + *-linux*) + AC_DEFINE([HAVE_LINUXTHREADS], [1], [using Linux pthread?]) + ;; + *-solaris*) + AC_DEFINE([_POSIX_PTHREAD_SEMANTICS], [1]) + AC_CHECK_FUNC( + [pthread_setconcurrency], + [AC_DEFINE([CALL_PTHREAD_SETCONCURRENCY], [1], + [why not HAVE_P_S?])], + [] + ) + ;; + *-sco-sysv*uw*|*-*-sysv*UnixWare*|*-*-sysv*OpenUNIX*) + AC_DEFINE([HAVE_UNIXWARE_SIGWAIT], [1], [deviant sigwait?]) + ;; + esac + hack_shutup_pthreadonceinit=no + case "$host" in + *-aix5.[[123]].*) + hack_shutup_pthreadonceinit=yes + ;; + *-solaris2.[[89]]) + hack_shutup_pthreadonceinit=yes + ;; + *-solaris2.1[[0-9]]) + AC_CACHE_CHECK( + [if extra braces are needed for PTHREAD_ONCE_INIT], + [ntp_cv_brace_pthread_once_init], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #include + ]], + [[ + static pthread_once_t once_test = + { PTHREAD_ONCE_INIT }; + ]] + )], + [ntp_cv_brace_pthread_once_init=yes], + [ntp_cv_brace_pthread_once_init=no] + )] + ) + case "$ntp_cv_brace_pthread_once_init" in + yes) + hack_shutup_pthreadonceinit=yes + esac + ;; + esac + case "$hack_shutup_pthreadonceinit" in + yes) + AC_DEFINE([ISC_PLATFORM_BRACEPTHREADONCEINIT], [1], + [Enclose PTHREAD_ONCE_INIT in extra braces?]) + esac + CFLAGS="$saved_CFLAGS" + AS_UNSET([saved_CFLAGS]) + ;; + *) + LIBISC_PTHREADS_NOTHREADS=nothreads + ;; +esac +AC_SUBST([LIBISC_PTHREADS_NOTHREADS]) +AM_CONDITIONAL([PTHREADS], [test "$have_pthreads" != "no"]) + +AC_CHECK_HEADERS([sys/clockctl.h]) + +AC_ARG_ENABLE( + [clockctl], [AS_HELP_STRING( - [--without-sntp], - [- disable building sntp and sntp/tests] + [--enable-clockctl], + [s Use /dev/clockctl for non-root clock control] )], + [ntp_use_dev_clockctl=$enableval], + [ntp_use_dev_clockctl=$ac_cv_header_sys_clockctl_h] +) + +AC_MSG_CHECKING([if we should use /dev/clockctl]) +AC_MSG_RESULT([$ntp_use_dev_clockctl]) + + +AC_CHECK_HEADERS([sys/capability.h sys/prctl.h]) + +AC_MSG_CHECKING([if we have linux capabilities (libcap)]) + +case "$ac_cv_header_sys_capability_h$ac_cv_header_sys_prctl_h" in + yesyes) + case "$host" in + mips-sgi-irix*) + ntp_have_linuxcaps=no + ;; + *) ntp_have_linuxcaps=yes + ;; + esac + ;; + *) + ntp_have_linuxcaps=no + ;; +esac + +AC_ARG_ENABLE( + [linuxcaps], + [AS_HELP_STRING( + [--enable-linuxcaps], + [+ Use Linux capabilities for non-root clock control] + )], + [ntp_have_linuxcaps=$enableval] +) + +AC_MSG_RESULT([$ntp_have_linuxcaps]) + +case "$ntp_have_linuxcaps" in + yes) + AC_DEFINE([HAVE_LINUX_CAPABILITIES], [1], + [Do we have Linux capabilities?]) + LIBS="$LIBS -lcap" + ;; +esac + +case "$ntp_use_dev_clockctl$ntp_have_linuxcaps" in + *yes*) + AC_DEFINE([HAVE_DROPROOT], [1], + [Can we drop root privileges?]) +esac + +dnl libntp wants to use sigaction() flag SA_RESTORER (to ignore it) but +dnl the public headers don't define it. On systems where's it's been +dnl seen, it's declared in /usr/include/asm/signal.h which is included +dnl by linux/signal.h +dnl case "$host" in +dnl *-*-linux*) +dnl AC_CHECK_HEADERS([linux/signal.h]) +dnl esac +dnl The above doesn't work due to "present but cannot be compiled" -- +dnl linux/signal.h is apparently a kernel header that conflicts with +dnl user headers. We may need to grep the SA_RESTORER definition out. + +case "$host" in + *-*-darwin*) + AC_SEARCH_LIBS([res_9_init], [resolv]) + ;; + *) AC_SEARCH_LIBS([res_init], [resolv]) + ;; +esac +AC_HEADER_RESOLV +#HMS: Why do we do this check so "early"? +AC_CHECK_FUNCS([res_init], , [AC_CHECK_FUNCS([__res_init])]) + +# We also need -lsocket, but we have tested for that already. +AC_CHECK_FUNC([inet_ntop], [], + [AC_DEFINE([ISC_PLATFORM_NEEDNTOP], [1], [ISC: provide inet_ntop()])]) +AC_CHECK_FUNC([inet_pton], [], + [AC_DEFINE([ISC_PLATFORM_NEEDPTON], [1], [ISC: provide inet_pton()])]) + +AC_CHECK_TYPES([uintptr_t, int32, u_int32]) + +AH_VERBATIM([TYPEDEF_UINTPTR_T], +[/* Provide a typedef for uintptr_t? */ +#ifndef HAVE_UINTPTR_T +typedef unsigned int uintptr_t; +#define HAVE_UINTPTR_T 1 +#endif]) + +case "$ac_cv_type_int32::$ac_cv_header_resolv_h" in + no::yes) + AC_CACHE_CHECK( + [for int32 with DNS headers included], + [ntp_cv_type_int32_with_dns], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #ifdef HAVE_ARPA_NAMESER_H + # include + #endif + #include + ]], + [[ + size_t cb = sizeof(int32); + ]] + )], + [ntp_cv_type_int32_with_dns=yes], + [ntp_cv_type_int32_with_dns=no] + )] + ) + case "$ntp_cv_type_int32_with_dns" in + yes) + AC_DEFINE([HAVE_INT32_ONLY_WITH_DNS], [1], + [int32 type in DNS headers, not others.]) + esac +esac + +case "$ac_cv_type_u_int32::$ac_cv_header_resolv_h" in + no::yes) + AC_CACHE_CHECK( + [for u_int32 with DNS headers included], + [ntp_cv_type_u_int32_with_dns], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #ifdef HAVE_ARPA_NAMESER_H + # include + #endif + #include + ]], + [[ + size_t cb = sizeof(u_int32); + ]] + )], + [ntp_cv_type_u_int32_with_dns=yes], + [ntp_cv_type_u_int32_with_dns=no] + )] + ) + case "$ntp_cv_type_u_int32_with_dns" in + yes) + AC_DEFINE([HAVE_U_INT32_ONLY_WITH_DNS], [1], + [u_int32 type in DNS headers, not others.]) + esac +esac + +AC_CHECK_HEADERS( + [sys/timepps.h], [], - [with_sntp="${withsntp=yes}"] + [], + [ + #ifdef HAVE_SYS_TIME_H + # include + #endif + #ifdef HAVE_ERRNO_H + # include + #endif + ] ) -case "$with_sntp" in - no) - SNTP= + +AC_CACHE_CHECK( + [for struct timespec], + [ntp_cv_struct_timespec], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #include + /* Under SunOS, timespec is in sys/timepps.h, + which needs errno.h and FRAC */ + #ifdef HAVE_ERRNO_H + # include + #endif + #ifdef HAVE_SYS_TIMEPPS_H + # define FRAC 4294967296 + # include + #endif + ]], + [[ + struct timespec n; + ]] + )], + [ntp_cv_struct_timespec=yes], + [ntp_cv_struct_timespec=no] + )] +) +case "$ntp_cv_struct_timespec" in + yes) + AC_DEFINE([HAVE_STRUCT_TIMESPEC], [1], [struct timespec declared?]) +esac + +AC_CACHE_CHECK( + [for struct ntptimeval], + [ntp_cv_struct_ntptimeval], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #include + #include + ]], + [[ + struct ntptimeval n; + ]] + )], + [ntp_cv_struct_ntptimeval=yes], + [ntp_cv_struct_ntptimeval=no] + )] +) +case "$ntp_cv_struct_ntptimeval" in + yes) + AC_DEFINE([HAVE_STRUCT_NTPTIMEVAL], [1], + [Do we have struct ntptimeval?]) +esac + +AC_CHECK_HEADERS( + [md5.h], + [], + [], + [ + #ifdef HAVE_SYS_TYPES_H + # include + #endif + ] +) + +AC_SEARCH_LIBS([MD5Init], [md5 md]) +AC_CHECK_FUNCS([MD5Init sysconf getdtablesize sigaction sigset sigvec]) + +AC_CACHE_CHECK( + [for SIGIO], + [ntp_cv_hdr_def_sigio], + [AC_EGREP_CPP( + [yes], + [ + #include + + #ifdef SIGIO + yes + #endif + ], + [ntp_cv_hdr_def_sigio=yes], + [ntp_cv_hdr_def_sigio=no] + )] + ) + +dnl Override those system that have a losing SIGIO +AC_MSG_CHECKING([if we want to use SIGIO]) +ans=no +case "$ntp_cv_hdr_def_sigio" in + yes) + ans=yes + case "$host" in + alpha*-dec-osf4*|alpha*-dec-osf5*) + ans=no + ;; + *-convex-*) + ans=no + ;; + *-dec-*) + ans=no + ;; + *-pc-cygwin*) + ans=no + ;; + *-sni-sysv*) + ans=no + ;; + *-univel-sysv*) + ans=no + ;; + *-*-irix6*) + ans=no + ;; + *-*-freebsd*) + ans=no + ;; + *-*-*linux*) + ans=no + ;; + *-*-unicosmp*) + ans=no + ;; + *-*-kfreebsd*) + ans=no + ;; + m68k-*-mint*) + ans=no + ;; + esac + ;; +esac +case "$ans" in + yes) + AC_DEFINE([HAVE_SIGNALED_IO], [1], + [Can we use SIGIO for tcp and udp IO?]) +esac +AC_MSG_RESULT([$ans]) + +AC_CACHE_CHECK( + [for SIGPOLL], + [ntp_cv_hdr_def_sigpoll], + [AC_EGREP_CPP( + [yes], + [ + #include + + #ifdef SIGPOLL + yes + #endif + ], + [ntp_cv_hdr_def_sigpoll=yes], + [ntp_cv_hdr_def_sigpoll=no] + )] +) + +AC_MSG_CHECKING([if we can use SIGPOLL for UDP I/O]) +ans=no +case "$ntp_cv_hdr_def_sigpoll" in + yes) + case "$host" in + mips-sgi-irix*) + ans=no + ;; + vax-dec-bsd) + ans=no + ;; + *-pc-cygwin*) + ans=no + ;; + *-sni-sysv*) + ans=no + ;; + *-*-aix[[456]]*) + ans=no + ;; + *-*-hpux*) + ans=no + ;; + *-*-*linux*) + ans=no + ;; + *-*-osf*) + ans=no + ;; + *-*-qnx*) + ans=no + ;; + *-*-sunos*) + ans=no + ;; + *-*-solaris*) + ans=no + ;; + *-*-ultrix*) + ans=no + ;; + *-*-unicosmp*) + ans=no + ;; + *-*-kfreebsd*) + ans=no + ;; + *) ans=yes + ;; + esac + ;; +esac +case "$ans" in + yes) + AC_DEFINE([USE_UDP_SIGPOLL], [1], [Can we use SIGPOLL for UDP?]) +esac +AC_MSG_RESULT([$ans]) + +AC_MSG_CHECKING([if we can use SIGPOLL for TTY I/O]) +ans=no +case "$ntp_cv_hdr_def_sigpoll" in + yes) + case "$host" in + mips-sgi-irix*) + ans=no + ;; + vax-dec-bsd) + ans=no + ;; + *-pc-cygwin*) + ans=no + ;; + *-sni-sysv*) + ans=no + ;; + *-*-aix[[456]]*) + ans=no + ;; + *-*-hpux*) + ans=no + ;; + *-*-*linux*) + ans=no + ;; + *-*-osf*) + ans=no + ;; + *-*-sunos*) + ans=no + ;; + *-*-ultrix*) + ans=no + ;; + *-*-qnx*) + ans=no + ;; + *-*-unicosmp*) + ans=no + ;; + *-*-kfreebsd*) + ans=no + ;; + *) ans=yes + ;; + esac + ;; +esac +case "$ans" in + yes) + AC_DEFINE([USE_TTY_SIGPOLL], [1], [Can we use SIGPOLL for tty IO?]) +esac +AC_MSG_RESULT([$ans]) + +AC_CACHE_CHECK( + [number of arguments to gettimeofday()], + [ntp_cv_func_Xettimeofday_nargs], + [AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ + #include + ]], + [[ + gettimeofday(0, 0); + settimeofday(0, 0); + ]] + )], + [ntp_cv_func_Xettimeofday_nargs=2], + [ntp_cv_func_Xettimeofday_nargs=1] + )] +) +case "$ntp_cv_func_Xettimeofday_nargs" in + 1) + AC_DEFINE([SYSV_TIMEOFDAY], [1], [Does Xettimeofday take 1 arg?]) +esac + +AC_CHECK_FUNCS([settimeofday], ,[ + case "$host" in + *-*-mpeix*) ac_cv_func_settimeofday=yes + esac +]) + +AC_MSG_CHECKING([if we'll use clock_settime or settimeofday or stime]) +ntp_warning='GRONK' +ans=none +case "$ac_cv_func_clock_settime$ac_cv_func_settimeofday$ac_cv_func_stime" in + yes*) + ntp_warning='' + ans='clock_settime()' + ;; + noyes*) + ntp_warning='But clock_settime() would be better (if we had it)' + ans='settimeofday()' + ;; + nonoyes) + ntp_warning='Which is the worst of the three' + ans='stime()' + ;; + *) + case "$build" in + $host) + ntp_warning='Which leaves us with nothing to use!' + esac +esac +AC_MSG_RESULT([$ans]) +case "$ntp_warning" in + '') ;; *) - SNTP=sntp + AC_MSG_WARN([*** $ntp_warning ***]) ;; esac -AC_SUBST([SNTP]) -AM_CONDITIONAL([BUILD_SNTP], [test -n "$SNTP"]) -AC_MSG_RESULT([$with_sntp]) + + +dnl add to LDADD_LIBNTP set by ntp_compiler.m4 +LDADD_LIBNTP="$LDADD_LIBNTP $LIBS" +LIBS=$__LIBS +AS_UNSET([__LIBS]) ])dnl dnl ====================================================================== diff --git a/sntp/m4/ntp_sntp.m4 b/sntp/m4/ntp_sntp.m4 new file mode 100644 index 000000000..a9d405eae --- /dev/null +++ b/sntp/m4/ntp_sntp.m4 @@ -0,0 +1,29 @@ +dnl ###################################################################### +dnl Common m4sh code SNTP +AC_DEFUN([NTP_WITHSNTP], [ + +dnl preset withsntp=no in env to change default to --without-sntp +AC_MSG_CHECKING([if sntp will be built]) +AC_ARG_WITH( + [sntp], + [AS_HELP_STRING( + [--without-sntp], + [- disable building sntp and sntp/tests] + )], + [], + [with_sntp="${withsntp=yes}"] +) +case "$with_sntp" in + no) + SNTP= + ;; + *) + SNTP=sntp + ;; +esac +AC_SUBST([SNTP]) +AM_CONDITIONAL([BUILD_SNTP], [test -n "$SNTP"]) +AC_MSG_RESULT([$with_sntp]) + +])dnl +dnl ====================================================================== diff --git a/sntp/main.c b/sntp/main.c index 17f128314..bd2cd64b0 100644 --- a/sntp/main.c +++ b/sntp/main.c @@ -1,33 +1,38 @@ #include +#include +#include + #include "main.h" +#include "ntp_libopts.h" #include "kod_management.h" #include "networking.h" #include "utilities.h" #include "log.h" #include "libntp.h" -#include -#include -#include +int shutting_down; +int time_derived; +int time_adjusted; int n_pending_dns = 0; int n_pending_ntp = 0; int ai_fam_pref = AF_UNSPEC; int ntpver = 4; double steplimit = -1; -int xmt_delay; SOCKET sock4 = -1; /* Socket for IPv4 */ SOCKET sock6 = -1; /* Socket for IPv6 */ /* ** BCAST *must* listen on port 123 (by default), so we can only -** use the UCST sockets, above if they too are using port 123 +** use the UCST sockets (above) if they too are using port 123 */ SOCKET bsock4 = -1; /* Broadcast Socket for IPv4 */ SOCKET bsock6 = -1; /* Broadcast Socket for IPv6 */ -char *progname; -struct event_base *base = NULL; -struct evdns_base *dnsbase = NULL; +struct event_base *base; +struct event *ev_sock4; +struct event *ev_sock6; +struct event *ev_worker_timeout; +struct event *ev_xmt_timer; struct dns_ctx { const char * name; @@ -41,22 +46,35 @@ struct dns_ctx { struct key * key; }; -struct xmt_ctx { - SOCKET sock; +typedef struct sent_pkt_tag sent_pkt; +struct sent_pkt_tag { + sent_pkt * link; struct dns_ctx * dctx; - struct ntp_ctx * nctx; + sockaddr_u addr; + time_t stime; + int done; + struct pkt x_pkt; }; -struct ntp_ctx { - struct dns_ctx * dctx; - struct evutil_addrinfo *ai; - struct pkt x_pkt; +typedef struct xmt_ctx_tag xmt_ctx; +struct xmt_ctx_tag { + xmt_ctx * link; + SOCKET sock; + time_t sched; + sent_pkt * spkt; }; -struct key *keys = NULL; -struct timeval timeout_tv; +struct timeval headspace; +xmt_ctx * xmt_q; +struct key * keys = NULL; +struct timeval bcst_timeout_tv; +int ucst_timeout; +/* check the timeout at least once per second */ +struct timeval ucst_wakeup_tv = { 0, 888888 }; -struct timeval ucst_timeout_tv = { 5, 0 }; +sent_pkt * fam_listheads[2]; +#define v4_pkts_list (fam_listheads[0]) +#define v6_pkts_list (fam_listheads[1]) static union { struct pkt pkt; @@ -65,29 +83,34 @@ static union { #define r_pkt rbuf.pkt -void open_sockets( void ); -void handle_lookup( const char *name, int flags ); -void dns_cb (int errcode, struct evutil_addrinfo *addr, void *ptr); -void queue_xmt( SOCKET sock, struct dns_ctx *dctx, struct ntp_ctx *nctx ); -void xmt_cb( evutil_socket_t, short, void *ptr ); -int checkKoD( struct evutil_addrinfo *ai ); -void ntp_cb (evutil_socket_t, short, void *); -void set_li_vn_mode (struct pkt *spkt, char leap, char version, char mode); -int sntp_main (int argc, char **argv); -int on_wire (struct addrinfo *host, struct addrinfo *bcastaddr); -int set_time (double offset); - -#define NORMALIZE_TIMEVAL(tv) \ -do { \ - while ((tv).tv_usec < 0) { \ - (tv).tv_usec += 1000000; \ - (tv).tv_sec--; \ - } \ - while ((tv).tv_usec > 999999) { \ - (tv).tv_usec -= 1000000; \ - (tv).tv_sec++; \ - } \ -} while (0) +#ifdef HAVE_DROPROOT +int droproot; /* intres imports these */ +int root_dropped; +#endif + +void open_sockets(void); +void handle_lookup(const char *name, int flags); +void sntp_addremove_fd(int fd, int is_pipe, int remove_it); +void worker_timeout(evutil_socket_t, short, void *); +void worker_resp_cb(evutil_socket_t, short, void *); +void sntp_name_resolved(int, int, void *, const char *, const char *, + const struct addrinfo *, + const struct addrinfo *); +void queue_xmt(SOCKET sock, struct dns_ctx *dctx, sent_pkt *spkt, + u_int xmt_delay); +void xmt_timer_cb(evutil_socket_t, short, void *ptr); +void xmt(xmt_ctx *xctx); +int check_kod(const struct addrinfo *ai); +void timeout_query(sent_pkt *); +void timeout_queries(void); +void sock_cb(evutil_socket_t, short, void *); +void check_exit_conditions(void); +void sntp_libevent_log_cb(int, const char *); +void set_li_vn_mode(struct pkt *spkt, char leap, char version, char mode); +int sntp_main(int argc, char **argv); +int set_time(double offset); +int libevent_version_ok(void); +int gettimeofday_cached(struct event_base *b, struct timeval *tv); /* @@ -99,13 +122,27 @@ sntp_main ( char **argv ) { - int i; - int optct; - long l; - - progname = argv[0]; - - optct = optionProcess(&sntpOptions, argc, argv); + int i; + int exitcode; + int optct; + struct event_config * evcfg; + + /* Initialize logging system - sets up progname */ + sntp_init_logging(argv[0]); + + if (!libevent_version_ok()) + exit(EX_SOFTWARE); + + init_lib(); + DPRINTF(2, ("init_lib() done, %s%s\n", + (ipv4_works) + ? "ipv4_works " + : "", + (ipv6_works) + ? "ipv6_works " + : "")); + + optct = ntpOptionProcess(&sntpOptions, argc, argv); argc -= optct; argv += optct; @@ -113,26 +150,29 @@ sntp_main ( DPRINTF(1, ("%s\n", Version)); ntpver = OPT_VALUE_NTPVERSION; + steplimit = OPT_VALUE_STEPLIMIT / 1e3; + headspace.tv_usec = max(0, OPT_VALUE_HEADSPACE * 1000); + headspace.tv_usec = min(headspace.tv_usec, 999999); - steplimit = (double) ( OPT_VALUE_STEPLIMIT ) / 1000; - - /* Initialize logging system */ - init_logging(); if (HAVE_OPT(FILELOG)) open_logfile(OPT_ARG(FILELOG)); if (0 == argc && !HAVE_OPT(BROADCAST) && !HAVE_OPT(CONCURRENT)) { - printf("%s: Must supply at least one of -b hostname, -c hostname, or hostname.\n", progname); + printf("%s: Must supply at least one of -b hostname, -c hostname, or hostname.\n", + progname); exit(EX_USAGE); } + /* ** Eventually, we probably want: ** - separate bcst and ucst timeouts ** - multiple --timeout values in the commandline */ - timeout_tv.tv_sec = OPT_VALUE_BCTIMEOUT; - timeout_tv.tv_usec = 0; + bcst_timeout_tv.tv_sec = OPT_VALUE_BCTIMEOUT; + bcst_timeout_tv.tv_usec = 0; + + ucst_timeout = OPT_VALUE_UCTIMEOUT; /* IPv6 available? */ if (isc_net_probeipv6() != ISC_R_SUCCESS) { @@ -153,7 +193,7 @@ sntp_main ( ** For embedded systems with no writable filesystem, ** -K /dev/null can be used to disable KoD storage. */ - kod_init_kod_db(OPT_ARG(KOD)); + kod_init_kod_db(OPT_ARG(KOD), FALSE); // HMS: Should we use arg-defalt for this too? if (HAVE_OPT(KEYFILE)) @@ -165,19 +205,28 @@ sntp_main ( ** ** HMS: What exactly does the above mean? */ - - base = event_base_new(); - if (!base) { - printf("%s: event_base_new() failed!\n", progname); + event_set_log_callback(&sntp_libevent_log_cb); + if (debug > 0) + event_enable_debug_mode(); + evcfg = event_config_new(); + if (NULL == evcfg) { + printf("%s: event_config_new() failed!\n", progname); return -1; } - - dnsbase = evdns_base_new(base, 1); - if (!dnsbase) { - printf("%s: evdns_base_new() failed!\n", progname); +#ifndef HAVE_SOCKETPAIR + event_config_require_features(evcfg, EV_FEATURE_FDS); +#endif + base = event_base_new_with_config(evcfg); + event_config_free(evcfg); + if (NULL == base) { + printf("%s: event_base_new() failed!\n", progname); return -1; } + /* wire into intres resolver */ + worker_per_query = TRUE; + addremove_io_fd = &sntp_addremove_fd; + open_sockets(); if (HAVE_OPT(BROADCAST)) { @@ -195,21 +244,24 @@ sntp_main ( const char ** cp = STACKLST_OPT( CONCURRENT ); while (cn-- > 0) { - handle_lookup(*cp, CTX_UCST|CTX_CONC); + handle_lookup(*cp, CTX_UCST | CTX_CONC); cp++; } } - for (i = 0; i < argc; ++i) { + for (i = 0; i < argc; ++i) handle_lookup(argv[i], CTX_UCST); - } event_base_dispatch(base); - - evdns_base_free(dnsbase, 0); event_base_free(base); - return 0; /* Might not want 0... */ + if (!time_adjusted && + (ENABLED_OPT(STEP) || ENABLED_OPT(SLEW))) + exitcode = 1; + else + exitcode = 0; + + return exitcode; } @@ -221,8 +273,10 @@ open_sockets( void ) { - sockaddr_u name; + sockaddr_u name; + int one_fam_works; + one_fam_works = FALSE; if (-1 == sock4) { sock4 = socket(PF_INET, SOCK_DGRAM, 0); if (-1 == sock4) { @@ -244,12 +298,24 @@ open_sockets( msyslog(LOG_ERR, "open_sockets: bind(sock4) failed: %m"); exit(1); } + + /* Register an NTP callback for recv/timeout */ + ev_sock4 = event_new(base, sock4, + EV_TIMEOUT | EV_READ | EV_PERSIST, + &sock_cb, NULL); + if (NULL == ev_sock4) { + msyslog(LOG_ERR, + "open_sockets: event_new(base, sock4) failed!"); + } else { + one_fam_works = TRUE; + event_add(ev_sock4, &ucst_wakeup_tv); + } } /* We may not always have IPv6... */ - if (-1 == sock6) { + if (-1 == sock6 && ipv6_works) { sock6 = socket(PF_INET6, SOCK_DGRAM, 0); - if (-1 == sock6) { + if (-1 == sock6 && ipv6_works) { /* error getting a socket */ msyslog(LOG_ERR, "open_sockets: socket(PF_INET6) failed: %m"); exit(1); @@ -268,6 +334,17 @@ open_sockets( msyslog(LOG_ERR, "open_sockets: bind(sock6) failed: %m"); exit(1); } + /* Register an NTP callback for recv/timeout */ + ev_sock6 = event_new(base, sock6, + EV_TIMEOUT | EV_READ | EV_PERSIST, + &sock_cb, NULL); + if (NULL == ev_sock6) { + msyslog(LOG_ERR, + "open_sockets: event_new(base, sock6) failed!"); + } else { + one_fam_works = TRUE; + event_add(ev_sock6, &ucst_wakeup_tv); + } } return; @@ -283,47 +360,50 @@ handle_lookup( int flags ) { - struct evutil_addrinfo hints; /* Local copy is OK */ - struct dns_ctx *dns_ctx; - long l; + struct addrinfo hints; /* Local copy is OK */ + struct dns_ctx *ctx; + long l; + char * name_copy; + size_t name_sz; + size_t octets; DPRINTF(1, ("handle_lookup(%s,%#x)\n", name, flags)); ZERO(hints); hints.ai_family = ai_fam_pref; - hints.ai_flags |= EVUTIL_AI_CANONNAME; - hints.ai_flags |= EVUTIL_AI_NUMERICSERV; + hints.ai_flags = AI_CANONNAME | Z_AI_NUMERICSERV; /* ** Unless we specify a socktype, we'll get at least two ** entries for each address: one for TCP and one for ** UDP. That's not what we want. */ - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - dns_ctx = emalloc(sizeof(*dns_ctx)); - memset(dns_ctx, 0, sizeof(*dns_ctx)); - - dns_ctx->name = name; - dns_ctx->flags = flags; - dns_ctx->timeout = - (flags & CTX_BCST) - ? timeout_tv - : ucst_timeout_tv - ; - - // The following should arguably be passed in... + hints.ai_socktype = SOCK_DGRAM; + hints.ai_protocol = IPPROTO_UDP; + + name_sz = 1 + strlen(name); + octets = sizeof(*ctx) + name_sz; + ctx = emalloc_zero(octets); + name_copy = (char *)(ctx + 1); + memcpy(name_copy, name, name_sz); + ctx->name = name_copy; + ctx->flags = flags; + ctx->timeout = (CTX_BCST & flags) + ? bcst_timeout_tv + : ucst_wakeup_tv; + + /* The following should arguably be passed in... */ if (ENABLED_OPT(AUTHENTICATION) && atoint(OPT_ARG(AUTHENTICATION), &l)) { - dns_ctx->key_id = l; - get_key(dns_ctx->key_id, &dns_ctx->key); + ctx->key_id = l; + get_key(ctx->key_id, &ctx->key); } else { - dns_ctx->key_id = -1; - dns_ctx->key = NULL; + ctx->key_id = -1; + ctx->key = NULL; } ++n_pending_dns; - evdns_getaddrinfo(dnsbase, name, "123", &hints, dns_cb, dns_ctx); + getaddrinfo_sometime(name, "123", &hints, 0, + &sntp_name_resolved, ctx); } @@ -337,56 +417,78 @@ handle_lookup( ** - decrement n_pending_dns */ void -dns_cb( - int errcode, - struct evutil_addrinfo *addr, - void *ptr +sntp_name_resolved( + int rescode, + int gai_errno, + void * context, + const char * name, + const char * service, + const struct addrinfo * hints, + const struct addrinfo * addr ) { - struct dns_ctx *dctx = ptr; - struct ntp_ctx *nctx; - - if (errcode) { - printf("%s -> %s\n", dctx->name, evutil_gai_strerror(errcode)); - } else { - struct event *ev; - struct evutil_addrinfo *ai; - -#ifdef DEBUG - if (debug > 2) - printf("%s [%s]\n", dctx->name, - (addr->ai_canonname) - ? addr->ai_canonname - : ""); + struct dns_ctx * dctx; + sent_pkt * spkt; + const struct addrinfo * ai; + SOCKET sock; + u_int xmt_delay_v4; + u_int xmt_delay_v6; + u_int xmt_delay; + size_t octets; + + xmt_delay_v4 = 0; + xmt_delay_v6 = 0; + dctx = context; + if (rescode) { +#ifdef EAI_SYSTEM + if (EAI_SYSTEM == rescode) { + errno = gai_errno; + mfprintf(stderr, "%s lookup error %m\n", + dctx->name); + } else #endif + fprintf(stderr, "%s lookup error %s\n", + dctx->name, gai_strerror(rescode)); + } else { + DPRINTF(3, ("%s [%s]\n", dctx->name, + (addr->ai_canonname != NULL) + ? addr->ai_canonname + : "")); - xmt_delay = 0; - for (ai = addr; ai; ai = ai->ai_next) { - SOCKET sock; + for (ai = addr; ai != NULL; ai = ai->ai_next) { - if (checkKoD(ai)) + if (check_kod(ai)) continue; - nctx = emalloc((sizeof *nctx)); - memset(nctx, 0, sizeof *nctx); - - nctx->dctx = dctx; - nctx->ai = ai; - switch (ai->ai_family) { + case AF_INET: sock = sock4; + xmt_delay = xmt_delay_v4; + xmt_delay_v4++; break; + case AF_INET6: + if (!ipv6_works) + continue; + sock = sock6; + xmt_delay = xmt_delay_v6; + xmt_delay_v6++; break; + default: - msyslog(LOG_ERR, "dns_cb: unexpected ai_family: %d", + msyslog(LOG_ERR, "sntp_name_resolved: unexpected ai_family: %d", ai->ai_family); exit(1); break; } + spkt = emalloc_zero(sizeof(*spkt)); + spkt->dctx = dctx; + octets = min(ai->ai_addrlen, sizeof(spkt->addr)); + memcpy(&spkt->addr, ai->ai_addr, octets); + /* ** We're waiting for a response for either unicast ** or broadcast, so... @@ -395,36 +497,12 @@ dns_cb( /* If this is for a unicast IP, queue a request */ if (dctx->flags & CTX_UCST) - queue_xmt(sock, dctx, nctx); - - /* - ** Register an NTP callback for the response - ** or broadcast. - */ - - /* - ** Do we need separate events if we are using - ** a wildcard socket for responses? - */ - ev = event_new(base, sock, - EV_TIMEOUT|EV_READ|EV_PERSIST, - ntp_cb, nctx); - if (NULL == ev) { - msyslog(LOG_ERR, - "dns_cb: event_new(base, sock) failed!"); - --n_pending_ntp; - /* What now? */ - } else { - event_add(ev, &(dctx->timeout)); - } + queue_xmt(sock, dctx, spkt, xmt_delay); } - evutil_freeaddrinfo(addr); - free(ptr); } - /* n_pending_dns really should be >0 here... */ - if (--n_pending_dns == 0 && n_pending_ntp == 0) - event_base_loopexit(base, NULL); + --n_pending_dns; + check_exit_conditions(); } @@ -433,76 +511,139 @@ dns_cb( */ void queue_xmt( - SOCKET sock, - struct dns_ctx *dctx, - struct ntp_ctx *nctx + SOCKET sock, + struct dns_ctx * dctx, + sent_pkt * spkt, + u_int xmt_delay ) { - struct event *ev; - struct xmt_ctx *xctx; - struct timeval cb_tv = { 2 * xmt_delay, 0 }; + sockaddr_u * dest; + sent_pkt ** pkt_listp; + xmt_ctx * xctx; + struct timeval start_cb; + struct timeval delay; + + dest = &spkt->addr; + if (IS_IPV6(dest)) + pkt_listp = &v6_pkts_list; + else + pkt_listp = &v4_pkts_list; - xctx = emalloc(sizeof(*xctx)); - memset(xctx, 0, sizeof(*xctx)); + LINK_SLIST(*pkt_listp, spkt, link); + xctx = emalloc_zero(sizeof(*xctx)); xctx->sock = sock; - xctx->dctx = dctx; - xctx->nctx = nctx; + xctx->spkt = spkt; + gettimeofday_cached(base, &start_cb); + xctx->sched = start_cb.tv_sec + (2 * xmt_delay); - /* - ** xmt_delay increases, starting with 0. - ** Queue an event for xmt_delay*2 seconds from now, - ** and when it "fires" send off a packet to the target. - */ - ev = evtimer_new(base, &xmt_cb, xctx); - if (NULL == ev) { - msyslog(LOG_ERR, "queue_xmt: evtimer_new() failed!"); - exit(1); + LINK_SORT_SLIST(xmt_q, xctx, (xctx->sched < L_S_S_CUR()->sched), + link, xmt_ctx); + if (xmt_q == xctx) { + /* + * The new entry is the first scheduled. The timer is + * either not active or is set for the second xmt + * context in xmt_q. + */ + if (NULL == ev_xmt_timer) + ev_xmt_timer = event_new(base, INVALID_SOCKET, + EV_TIMEOUT, + &xmt_timer_cb, NULL); + if (NULL == ev_xmt_timer) { + msyslog(LOG_ERR, + "queue_xmt: event_new(base, -1, EV_TIMEOUT) failed!"); + exit(1); + } + ZERO(delay); + if (xctx->sched > start_cb.tv_sec) + delay.tv_sec = xctx->sched - start_cb.tv_sec; + event_add(ev_xmt_timer, &delay); + DPRINTF(2, ("queue_xmt: xmt timer for %u usec\n", + (u_int)delay.tv_usec)); } +} - ++xmt_delay; - - evtimer_add(ev, &cb_tv); - return; +/* +** xmt_timer_cb +*/ +void +xmt_timer_cb( + evutil_socket_t fd, + short what, + void * ctx + ) +{ + struct timeval start_cb; + struct timeval delay; + xmt_ctx * x; + + UNUSED_ARG(fd); + UNUSED_ARG(ctx); + DEBUG_INSIST(EV_TIMEOUT == what); + + if (NULL == xmt_q || shutting_down) + return; + gettimeofday_cached(base, &start_cb); + if (xmt_q->sched <= start_cb.tv_sec) { + UNLINK_HEAD_SLIST(x, xmt_q, link); + DPRINTF(2, ("xmt_timer_cb: at .%6.6u -> %s", + (u_int)start_cb.tv_usec, stoa(&x->spkt->addr))); + xmt(x); + free(x); + if (NULL == xmt_q) + return; + } + if (xmt_q->sched <= start_cb.tv_sec) { + event_add(ev_xmt_timer, &headspace); + DPRINTF(2, ("xmt_timer_cb: at .%6.6u headspace %6.6u\n", + (u_int)start_cb.tv_usec, + (u_int)headspace.tv_usec)); + } else { + delay.tv_sec = xmt_q->sched - start_cb.tv_sec; + delay.tv_usec = 0; + event_add(ev_xmt_timer, &delay); + DPRINTF(2, ("xmt_timer_cb: at .%6.6u next %ld seconds\n", + (u_int)start_cb.tv_usec, + (long)delay.tv_sec)); + } } /* -** xmt_cb +** xmt() */ void -xmt_cb( - evutil_socket_t fd, - short what, - void *ptr +xmt( + xmt_ctx * xctx ) { - struct xmt_ctx *xctx = ptr; SOCKET sock = xctx->sock; - struct dns_ctx *dctx = xctx->dctx; - struct ntp_ctx *nctx = xctx->nctx; - struct evutil_addrinfo *ai = nctx->ai; + struct dns_ctx *dctx = xctx->spkt->dctx; + sent_pkt * spkt = xctx->spkt; + sockaddr_u * dst = &spkt->addr; struct timeval tv_xmt; struct pkt x_pkt; int pkt_len; if (0 != GETTIMEOFDAY(&tv_xmt, NULL)) { msyslog(LOG_ERR, - "xmt_cb: gettimeofday() failed: %m"); + "xmt: gettimeofday() failed: %m"); exit(1); } tv_xmt.tv_sec += JAN_1970; - pkt_len = generate_pkt(&x_pkt, &tv_xmt, - dctx->key_id, dctx->key); + pkt_len = generate_pkt(&x_pkt, &tv_xmt, dctx->key_id, + dctx->key); /* The current sendpkt does not return status */ - sendpkt(sock, (sockaddr_u *)ai->ai_addr, &x_pkt, pkt_len); + sendpkt(sock, dst, &x_pkt, pkt_len); /* Save the packet we sent... */ - memcpy(&(nctx->x_pkt), &x_pkt, pkt_len); + memcpy(&spkt->x_pkt, &x_pkt, min(sizeof(spkt->x_pkt), pkt_len)); + spkt->stime = tv_xmt.tv_sec - JAN_1970; - DPRINTF(2, ("xmt_cb: UCST: Current time sec: %i msec: %i\n", (unsigned int) tv_xmt.tv_sec, (unsigned int) tv_xmt.tv_usec)); + DPRINTF(2, ("xmt: %lu.%6.6u %s %s\n", (u_long)tv_xmt.tv_sec, + (u_int)tv_xmt.tv_usec, dctx->name, stoa(dst))); /* ** If the send fails: @@ -515,11 +656,62 @@ xmt_cb( /* -** checkKoD + * timeout_queries() -- give up on unrequited NTP queries + */ +void +timeout_queries(void) +{ + struct timeval start_cb; + u_int idx; + sent_pkt * head; + sent_pkt * spkt; + sent_pkt * spkt_next; + long age; + + gettimeofday_cached(base, &start_cb); + for (idx = 0; idx < COUNTOF(fam_listheads); idx++) { + head = fam_listheads[idx]; + for (spkt = head; spkt != NULL; spkt = spkt_next) { + spkt_next = spkt->link; + if (0 == spkt->stime || spkt->done) + continue; + age = start_cb.tv_sec - spkt->stime; + DPRINTF(3, ("%s %s age %ld\n", stoa(&spkt->addr), + spkt->dctx->name, age)); + if (age > ucst_timeout) + timeout_query(spkt); + } + } +} + + +void timeout_query( + sent_pkt * spkt + ) +{ + sockaddr_u * server; + + spkt->done = TRUE; + server = &spkt->addr; + msyslog(LOG_NOTICE, "%s %s no response after %d seconds", + spkt->dctx->name, stoa(server), ucst_timeout); + if (n_pending_ntp > 0) { + --n_pending_ntp; + check_exit_conditions(); + } else { + INSIST(0 == n_pending_ntp); + DPRINTF(1, ("n_pending_ntp reached zero before dec for %s %s\n", + spkt->dctx->name, stoa(server))); + } +} + + +/* +** check_kod */ int -checkKoD( - struct evutil_addrinfo *ai +check_kod( + const struct addrinfo * ai ) { char *hostname; @@ -527,7 +719,7 @@ checkKoD( /* Is there a KoD on file for this address? */ hostname = addrinfo_to_str(ai); - DPRINTF(2, ("checkKoD: checking <%s>\n", hostname)); + DPRINTF(2, ("check_kod: checking <%s>\n", hostname)); if (search_entry(hostname, &reason)) { printf("prior KoD for %s, skipping.\n", hostname); @@ -543,7 +735,7 @@ checkKoD( /* -** NTP Callback: +** Socket readable/timeout Callback: ** Read in the packet ** Unicast: ** - close socket @@ -553,57 +745,285 @@ checkKoD( ** - If packet is good, set the time and "exit" */ void -ntp_cb( +sock_cb( evutil_socket_t fd, short what, void *ptr ) { - struct ntp_ctx *nctx = ptr; - int rpktl; - int rc; - -#ifdef DEBUG - if (debug > 1) - printf("ntp_cb: event on socket %d:%s%s%s%s [%s%s] <%s>\n", - (int) fd, + sockaddr_u sender; + sockaddr_u * psau; + sent_pkt * pktlist; + sent_pkt * spkt; + int rpktl; + int rc; + + INSIST(sock4 == fd || sock6 == fd); + DPRINTF(3, ("sock_cb: event on sock%s:%s%s%s%s [UCST]\n", + (fd == sock6) + ? "6" + : "4", (what & EV_TIMEOUT) ? " timeout" : "", (what & EV_READ) ? " read" : "", (what & EV_WRITE) ? " write" : "", - (what & EV_SIGNAL) ? " signal" : "", - (nctx->dctx->flags & CTX_BCST) ? "BCST" : "", - (nctx->dctx->flags & CTX_UCST) ? "UCST" : "", - nctx->dctx->name - ); -#endif + (what & EV_SIGNAL) ? " signal" : "")); + + if (!(EV_READ & what)) { + if (EV_TIMEOUT & what) + timeout_queries(); + + return; + } /* Read in the packet */ - rpktl = recvpkt(fd, &r_pkt, sizeof rbuf, - (nctx->dctx->flags & CTX_UCST) ? &(nctx->x_pkt) : 0); + rpktl = recvdata(fd, &sender, &r_pkt, sizeof(rbuf)); + if (rpktl < 0) { + msyslog(LOG_DEBUG, "recvfrom error %m"); + return; + } - DPRINTF(2, ("ntp_cb: recvpkt returned %x\n", rpktl)); + if (sock6 == fd) + pktlist = v6_pkts_list; + else + pktlist = v4_pkts_list; - /* If this is a Unicast packet, we're done ... */ - if (nctx->dctx->flags & CTX_UCST) { - /* Only close() if we use a separate socket for each response */ - // close(fd); - --n_pending_ntp; + for (spkt = pktlist; spkt != NULL; spkt = spkt->link) { + psau = &spkt->addr; + if (SOCK_EQ(&sender, psau)) + break; + } + if (NULL == spkt) { + msyslog(LOG_WARNING, + "Packet from unexpected source %s dropped", + sptoa(&sender)); + return; } + DPRINTF(1, ("sock_cb: %s %s\n", spkt->dctx->name, + sptoa(&sender))); + + rpktl = process_pkt(&r_pkt, &sender, rpktl, MODE_SERVER, + &spkt->x_pkt, "sock_cb"); + + DPRINTF(2, ("sock_cb: process_pkt returned %d\n", rpktl)); + + /* If this is a Unicast packet, one down ... */ + if (!spkt->done && CTX_UCST & spkt->dctx->flags) { + if (n_pending_ntp > 0) { + --n_pending_ntp; + } else { + INSIST(0 == n_pending_ntp); + DPRINTF(1, ("n_pending_ntp reached zero before dec for %s %s\n", + spkt->dctx->name, stoa(&sender))); + } + spkt->done = TRUE; + } + + /* If the packet is good, set the time and we're all done */ - rc = handle_pkt(rpktl, &r_pkt, nctx->ai); + rc = handle_pkt(rpktl, &r_pkt, &spkt->addr, spkt->dctx->name); + if (0 != rc) + DPRINTF(1, ("sock_cb: handle_pkt() returned %d\n", rc)); + check_exit_conditions(); +} + + +/* + * check_exit_conditions() + * + * If sntp has a reply, ask the event loop to stop after this round of + * callbacks, unless --wait was used. + */ +void +check_exit_conditions(void) +{ + if ((0 == n_pending_ntp && 0 == n_pending_dns) || + (time_derived && !HAVE_OPT(WAIT))) { + event_base_loopexit(base, NULL); + shutting_down = TRUE; + } else { + DPRINTF(2, ("%d NTP and %d name queries pending\n", + n_pending_ntp, n_pending_dns)); + } +} + + +/* + * sntp_addremove_fd() is invoked by the intres blocking worker code + * to read from a pipe, or to stop same. + */ +void sntp_addremove_fd( + int fd, + int is_pipe, + int remove_it + ) +{ + u_int idx; + blocking_child *c; + struct event * ev; + +#ifdef HAVE_SOCKETPAIR + if (is_pipe) { + /* sntp only asks for EV_FEATURE_FDS without HAVE_SOCKETPAIR */ + msyslog(LOG_ERR, "fatal: pipes not supported on systems with socketpair()"); + exit(1); + } +#endif + + c = NULL; + for (idx = 0; idx < blocking_children_alloc; idx++) { + c = blocking_children[idx]; + if (NULL == c) + continue; + if (fd == c->resp_read_pipe) + break; + } + if (idx == blocking_children_alloc) + return; + + if (remove_it) { + ev = c->resp_read_ctx; + c->resp_read_ctx = NULL; + event_del(ev); + event_free(ev); + + return; + } + + ev = event_new(base, fd, EV_READ | EV_PERSIST, + &worker_resp_cb, c); + if (NULL == ev) { + msyslog(LOG_ERR, + "sntp_addremove_fd: event_new(base, fd) failed!"); + return; + } + c->resp_read_ctx = ev; + event_add(ev, NULL); +} + + +/* called by forked intres child to close open descriptors */ +#ifdef WORK_FORK +void +kill_asyncio( + int startfd + ) +{ + if (INVALID_SOCKET != sock4) { + closesocket(sock4); + sock4 = INVALID_SOCKET; + } + if (INVALID_SOCKET != sock6) { + closesocket(sock6); + sock6 = INVALID_SOCKET; + } + if (INVALID_SOCKET != bsock4) { + closesocket(sock4); + sock4 = INVALID_SOCKET; + } + if (INVALID_SOCKET != bsock6) { + closesocket(sock6); + sock6 = INVALID_SOCKET; + } +} +#endif + + +/* + * worker_resp_cb() is invoked when resp_read_pipe is readable. + */ +void +worker_resp_cb( + evutil_socket_t fd, + short what, + void * ctx /* blocking_child * */ + ) +{ + blocking_child * c; + + DEBUG_INSIST(EV_READ & what); + c = ctx; + DEBUG_INSIST(fd == c->resp_read_pipe); + process_blocking_resp(c); +} + + +/* + * intres_timeout_req(s) is invoked in the parent to schedule an idle + * timeout to fire in s seconds, if not reset earlier by a call to + * intres_timeout_req(0), which clears any pending timeout. When the + * timeout expires, worker_idle_timer_fired() is invoked (again, in the + * parent). + * + * sntp and ntpd each provide implementations adapted to their timers. + */ +void +intres_timeout_req( + u_int seconds /* 0 cancels */ + ) +{ + struct timeval tv_to; + + if (NULL == ev_worker_timeout) { + ev_worker_timeout = event_new(base, -1, + EV_TIMEOUT | EV_PERSIST, + &worker_timeout, NULL); + DEBUG_INSIST(NULL != ev_worker_timeout); + } else { + event_del(ev_worker_timeout); + } + if (0 == seconds) + return; + tv_to.tv_sec = seconds; + tv_to.tv_usec = 0; + event_add(ev_worker_timeout, &tv_to); +} + + +void +worker_timeout( + evutil_socket_t fd, + short what, + void * ctx + ) +{ + UNUSED_ARG(fd); + UNUSED_ARG(ctx); + + DEBUG_REQUIRE(EV_TIMEOUT & what); + worker_idle_timer_fired(); +} + + +void +sntp_libevent_log_cb( + int severity, + const char * msg + ) +{ + int level; + + switch (severity) { - switch (rc) { - case 0: - // Should clean up and exit... - exit(0); - break; default: - printf("ntp_cb: handle_pkt() returned %d\n", rc); + case _EVENT_LOG_DEBUG: + level = LOG_DEBUG; + break; + + case _EVENT_LOG_MSG: + level = LOG_NOTICE; + break; + + case _EVENT_LOG_WARN: + level = LOG_WARNING; + break; + + case _EVENT_LOG_ERR: + level = LOG_ERR; break; } - event_base_loopexit(base, NULL); + msyslog(level, "%s", msg); } @@ -615,23 +1035,24 @@ generate_pkt ( struct key *pkt_key ) { - l_fp xmt; - int pkt_len = LEN_PKT_NOMAC; - - memset(x_pkt, 0, sizeof(struct pkt)); - TVTOTS(tv_xmt, &xmt); - HTONL_FP(&xmt, &(x_pkt->xmt)); + l_fp xmt_fp; + int pkt_len; + int mac_size; + + pkt_len = LEN_PKT_NOMAC; + ZERO(*x_pkt); + TVTOTS(tv_xmt, &xmt_fp); + HTONL_FP(&xmt_fp, &x_pkt->xmt); x_pkt->stratum = STRATUM_TO_PKT(STRATUM_UNSPEC); x_pkt->ppoll = 8; /* FIXME! Modus broadcast + adr. check -> bdr. pkt */ set_li_vn_mode(x_pkt, LEAP_NOTINSYNC, ntpver, 3); if (pkt_key != NULL) { - int mac_size = 20; /* max room for MAC */ - x_pkt->exten[0] = htonl(key_id); + mac_size = 20; /* max room for MAC */ mac_size = make_mac((char *)x_pkt, pkt_len, mac_size, pkt_key, (char *)&x_pkt->exten[1]); - if (mac_size) + if (mac_size > 0) pkt_len += mac_size + 4; } return pkt_len; @@ -639,59 +1060,59 @@ generate_pkt ( int -handle_pkt ( - int rpktl, - struct pkt *rpkt, - struct addrinfo *host +handle_pkt( + int rpktl, + struct pkt * rpkt, + sockaddr_u * host, + const char * hostname ) { - struct timeval tv_dst; - int sw_case, digits; - char *hostname = NULL, *ref, *ts_str = NULL; - double offset, precision, root_dispersion; - char addr_buf[INET6_ADDRSTRLEN]; - char *p_SNTP_PRETEND_TIME; - time_t pretend_time; + const char * addrtxt; + struct timeval tv_dst; + int sw_case; + int digits; + char * ref; + char * ts_str; + double offset; + double precision; + double root_dispersion; + char * p_SNTP_PRETEND_TIME; + time_t pretend_time; #if SIZEOF_TIME_T == 8 - long long ll; + long long ll; #else - long l; + long l; #endif + ts_str = NULL; + if (rpktl > 0) sw_case = 1; else sw_case = rpktl; - switch(sw_case) { - case SERVER_UNUSEABLE: + switch (sw_case) { + + case SERVER_UNUSEABLE: return -1; break; - case PACKET_UNUSEABLE: + case PACKET_UNUSEABLE: break; - case SERVER_AUTH_FAIL: + case SERVER_AUTH_FAIL: break; - case KOD_DEMOBILIZE: + case KOD_DEMOBILIZE: /* Received a DENY or RESTR KOD packet */ - hostname = addrinfo_to_str(host); + addrtxt = stoa(host); ref = (char *)&rpkt->refid; - add_entry(hostname, ref); - -#ifdef DEBUG - if (debug) - printf("sntp handle_pkt: Received KOD packet with code: %c%c%c%c from %s, demobilizing all connections\n", - ref[0], ref[1], ref[2], ref[3], - hostname); -#endif - - msyslog(LOG_WARNING, "Received a KOD packet with code %c%c%c%c from %s, demobilizing all connections", - ref[0], ref[1], ref[2], ref[3], hostname); + add_entry(addrtxt, ref); + msyslog(LOG_WARNING, "KOD code %c%c%c%c from %s %s", + ref[0], ref[1], ref[2], ref[3], addrtxt, hostname); break; - case KOD_RATE: + case KOD_RATE: /* ** Hmm... ** We should probably call add_entry() with an @@ -700,17 +1121,11 @@ handle_pkt ( */ break; - case 1: -#ifdef DEBUG - if (debug > 2) { - getnameinfo(host->ai_addr, host->ai_addrlen, addr_buf, - sizeof(addr_buf), NULL, 0, NI_NUMERICHOST); - printf("sntp handle_pkt: Received %i bytes from %s\n", - rpktl, addr_buf); - } -#endif + case 1: + DPRINTF(3, ("handle_pkt: %d bytes from %s %s\n", + rpktl, stoa(host), hostname)); - GETTIMEOFDAY(&tv_dst, (struct timezone *)NULL); + gettimeofday_cached(base, &tv_dst); p_SNTP_PRETEND_TIME = getenv("SNTP_PRETEND_TIME"); if (p_SNTP_PRETEND_TIME) { @@ -730,6 +1145,7 @@ handle_pkt ( offset_calculation(rpkt, rpktl, &tv_dst, &offset, &precision, &root_dispersion); + time_derived = TRUE; for (digits = 0; (precision *= 10.) < 1.; ++digits) /* empty */ ; @@ -737,22 +1153,23 @@ handle_pkt ( digits = 6; ts_str = tv_to_str(&tv_dst); - printf("%s ", ts_str); - if (offset > 0) - printf("+"); - printf("%.*f", digits, offset); + printf("%s %+.*f", ts_str, digits, offset); if (root_dispersion > 0.) - printf(" +/- %f secs", root_dispersion); - printf("\n"); + printf(" +/- %f ", root_dispersion); + printf(" %s %s%s\n", hostname, stoa(host), + (time_adjusted) + ? " [excess]" + : ""); free(ts_str); if (p_SNTP_PRETEND_TIME) return 0; - if (ENABLED_OPT(STEP) || ENABLED_OPT(SLEW)) + if (!time_adjusted && + (ENABLED_OPT(STEP) || ENABLED_OPT(SLEW))) return set_time(offset); - return 0; + return EX_OK; } return 1; @@ -856,44 +1273,134 @@ set_li_vn_mode ( /* -** set_time corrects the local clock by offset with either -** settimeofday() oradjtime()/adjusttimeofday(). +** set_time applies 'offset' to the local clock. */ int set_time( double offset ) { - struct timeval tp; - - /* check offset against steplimit */ - if (fabs(offset) > steplimit || !ENABLED_OPT(SLEW)) { - if (ENABLED_OPT(STEP)) { - GETTIMEOFDAY(&tp, NULL); + int rc; - tp.tv_sec += (long)offset; - tp.tv_usec += 1e6 * (offset - (long)offset); - NORMALIZE_TIMEVAL(tp); + if (time_adjusted) + return EX_OK; - if (SETTIMEOFDAY(&tp, NULL) < 0) { - msyslog(LOG_ERR, "Time not set: settimeofday(): %m"); - return -1; - } - return 0; - } + /* + ** If we can step but we cannot slew, then step. + ** If we can step or slew and and |offset| > steplimit, then step. + */ + if (ENABLED_OPT(STEP) && + ( !ENABLED_OPT(SLEW) + || (ENABLED_OPT(SLEW) && (fabs(offset) > steplimit)) + )) { + rc = step_systime(offset); + + /* If there was a problem, can we rely on errno? */ + if (1 == rc) + time_adjusted = TRUE; + return (time_adjusted) + ? EX_OK + : 1; + /* + ** In case of error, what should we use? + ** EX_UNAVAILABLE? + ** EX_OSERR? + ** EX_NOPERM? + */ } if (ENABLED_OPT(SLEW)) { - tp.tv_sec = (long)offset; - tp.tv_usec = 1e6 * (offset - (long)offset); - NORMALIZE_TIMEVAL(tp); + rc = adj_systime(offset); + + /* If there was a problem, can we rely on errno? */ + if (1 == rc) + time_adjusted = TRUE; + return (time_adjusted) + ? EX_OK + : 1; + /* + ** In case of error, what should we use? + ** EX_UNAVAILABLE? + ** EX_OSERR? + ** EX_NOPERM? + */ + } - if (ADJTIMEOFDAY(&tp, NULL) < 0) { - msyslog(LOG_ERR, "Time not set: adjtime(): %m"); - return -1; - } + return EX_SOFTWARE; +} + + +int +libevent_version_ok(void) +{ + ev_uint32_t v_compile_maj; + ev_uint32_t v_run_maj; + + v_compile_maj = LIBEVENT_VERSION_NUMBER & 0xffff0000; + v_run_maj = event_get_version_number() & 0xffff0000; + if (v_compile_maj != v_run_maj) { + fprintf(stderr, + "Incompatible libevent versions: have %s, built with %s\n", + event_get_version(), + LIBEVENT_VERSION); return 0; } + return 1; +} - return -1; + +int +gettimeofday_cached( + struct event_base * b, + struct timeval * caller_tv + ) +{ +#if defined(_EVENT_HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) + static struct event_base * cached_b; + static struct timeval cached; + static struct timeval adj_cached; + static struct timeval offset; + static int offset_ready; + struct timeval latest; + struct timeval systemt; + struct timespec ts; + struct timeval mono; + struct timeval diff; + int rc; + + event_base_gettimeofday_cached(b, &latest); + if (b == cached_b && + !memcmp(&latest, &cached, sizeof(latest))) { + *caller_tv = adj_cached; + return 0; + } + cached = latest; + cached_b = b; + if (!offset_ready) { + rc = clock_gettime(CLOCK_MONOTONIC, &ts); + if (0 == rc) { + rc = evutil_gettimeofday(&systemt, NULL); + if (0 != rc) { + msyslog(LOG_ERR, + "%s: gettimeofday() error %m", + progname); + exit(1); + } + mono.tv_sec = ts.tv_sec; + mono.tv_usec = ts.tv_nsec / 1000; + evutil_timersub(&systemt, &mono, &diff); + if (labs((long)diff.tv_sec) > 3600) { + offset = diff; + } + } + offset_ready = TRUE; + } + evutil_timeradd(&cached, &offset, &adj_cached); + *caller_tv = adj_cached; + + return 0; +#else + return event_base_gettimeofday_cached(b, caller_tv); +#endif } + diff --git a/sntp/main.h b/sntp/main.h index ab4135033..4c7d9b7e1 100644 --- a/sntp/main.h +++ b/sntp/main.h @@ -1,29 +1,31 @@ #ifndef MAIN_H #define MAIN_H -#include -#include -#include -#include -#include -#include +#include #include #include -#include + +#include +#include +#include +#include +#include +#include #include #include "crypto.h" -void set_li_vn_mode (struct pkt *spkt, char leap, char version, char mode); -int sntp_main (int argc, char **argv); -int generate_pkt (struct pkt *x_pkt, const struct timeval *tv_xmt, +void set_li_vn_mode(struct pkt *spkt, char leap, char version, char mode); +int sntp_main(int argc, char **argv); +int generate_pkt(struct pkt *x_pkt, const struct timeval *tv_xmt, int key_id, struct key *pkt_key); -int handle_pkt (int rpktl, struct pkt *rpkt, struct addrinfo *host); -void offset_calculation (struct pkt *rpkt, int rpktl, struct timeval *tv_dst, - double *offset, double *precision, - double *root_dispersion); -int on_wire (struct addrinfo *host, struct addrinfo *bcastaddr); -int set_time (double offset); +int handle_pkt(int rpktl, struct pkt *rpkt, sockaddr_u *host, + const char *hostname); +void offset_calculation(struct pkt *rpkt, int rpktl, + struct timeval *tv_dst, double *offset, + double *precision, double *root_dispersion); +int on_wire(struct addrinfo *host, struct addrinfo *bcastaddr); +int set_time(double offset); #endif /* MAIN_H */ diff --git a/sntp/networking.c b/sntp/networking.c index 3cb9f1c6d..bf213a127 100644 --- a/sntp/networking.c +++ b/sntp/networking.c @@ -39,64 +39,43 @@ sendpkt ( } -/* -** Fetch data, check if it's data for us and whether it's useable or not. -** -** If not, return a failure code so we can delete this server from our list -** and continue with another one. -*/ -int -recvpkt ( - SOCKET rsock, - struct pkt *rpkt, /* received packet (response) */ - unsigned int rsize, /* size of rpkt buffer */ - struct pkt *spkt /* sent packet (request) */ - ) -{ - int pkt_len; - sockaddr_u sender; - - pkt_len = recvdata(rsock, &sender, (char *)rpkt, rsize); - if (pkt_len > 0) - pkt_len = process_pkt(rpkt, &sender, pkt_len, MODE_SERVER, spkt, "recvpkt"); - - return pkt_len; -} - - /* Receive raw data */ int recvdata( - SOCKET rsock, - sockaddr_u *sender, - char *rdata, - int rdata_length + SOCKET rsock, + sockaddr_u * sender, + struct pkt * rdata, + int rdata_length ) { GETSOCKNAME_SOCKLEN_TYPE slen; int recvc; slen = sizeof(*sender); - recvc = recvfrom(rsock, rdata, rdata_length, 0, + recvc = recvfrom(rsock, (void *)rdata, rdata_length, 0, &sender->sa, &slen); - if (-1 == recvc) { - msyslog(LOG_ERR, "recvdata(%d) failed: %m", rsock); + if (recvc < 0) return recvc; - } #ifdef DEBUG if (debug > 2) { printf("Received %d bytes from %s:\n", recvc, sptoa(sender)); - pkt_output((struct pkt *)rdata, recvc, stdout); + pkt_output(rdata, recvc, stdout); } #endif return recvc; } +/* +** Check if it's data for us and whether it's useable or not. +** +** If not, return a failure code so we can delete this server from our list +** and continue with another one. +*/ int process_pkt ( struct pkt *rpkt, - sockaddr_u *sas, + sockaddr_u *sender, int pkt_len, int mode, struct pkt *spkt, @@ -105,10 +84,12 @@ process_pkt ( { unsigned int key_id = 0; struct key *pkt_key = NULL; - int is_authentic = -1; + int is_authentic; unsigned int exten_words, exten_words_used = 0; int mac_size; + is_authentic = (HAVE_OPT(AUTHENTICATION)) ? 0 : -1; + /* * Parse the extension field if present. We figure out whether * an extension field is present by measuring the MAC size. If @@ -142,14 +123,17 @@ unusable: } switch (exten_words) { - case 0: + + case 0: break; - case 1: + + case 1: key_id = ntohl(rpkt->exten[exten_words_used]); printf("Crypto NAK = 0x%08x\n", key_id); break; - case 5: - case 6: + + case 5: + case 6: /* ** Look for the key used by the server in the specified ** keyfile and if existent, fetch it or else leave the @@ -168,33 +152,34 @@ unusable: ** keyfile and compare those md5sums. */ mac_size = exten_words << 2; - if (!auth_md5((char *)rpkt, pkt_len - mac_size, mac_size - 4, pkt_key)) { - is_authentic = 0; + if (!auth_md5((char *)rpkt, pkt_len - mac_size, + mac_size - 4, pkt_key)) { + is_authentic = FALSE; break; } /* Yay! Things worked out! */ - if (debug) { - char *hostname = ss_to_str(sas); - - printf("sntp %s: packet received from %s successfully authenticated using key id %i.\n", - func_name, hostname, key_id); - free(hostname); - } - is_authentic = 1; + is_authentic = TRUE; + DPRINTF(1, ("sntp %s: packet from %s authenticated using key id %d.\n", + func_name, stoa(sender), key_id)); break; - default: + + default: goto unusable; break; } switch (is_authentic) { + case -1: /* unknown */ break; + case 0: /* not authentic */ return SERVER_AUTH_FAIL; break; + case 1: /* authentic */ break; + default: /* error */ break; } diff --git a/sntp/networking.h b/sntp/networking.h index bb7f2d2ea..d2d066559 100644 --- a/sntp/networking.h +++ b/sntp/networking.h @@ -34,14 +34,13 @@ /* From ntpdate.c */ -void sendpkt (SOCKET rsock, sockaddr_u *dest, struct pkt *pkt, int len); - -int recvdata (SOCKET rsock, sockaddr_u *sender, char *rdata, int rdata_len); - -int recvpkt (SOCKET rsock, struct pkt *rpkt, unsigned int rsize, struct pkt *spkt); - -int process_pkt (struct pkt *rpkt, sockaddr_u *sas, int pkt_len, - int mode, struct pkt *spkt, const char *func_name); +void sendpkt(SOCKET rsock, sockaddr_u *dest, struct pkt *pkt, int len); +int recvdata(SOCKET rsock, sockaddr_u *sender, struct pkt *rdata, + int rdata_len); +int recvpkt(SOCKET rsock, struct pkt *rpkt, unsigned int rsize, + struct pkt *spkt); +int process_pkt(struct pkt *rpkt, sockaddr_u *sas, int pkt_len, + int mode, struct pkt *spkt, const char *func_name); /* Shortened peer structure. Not absolutely necessary yet */ struct speer { diff --git a/sntp/sntp-opts.c b/sntp/sntp-opts.c index c22583534..97a16b8bd 100644 --- a/sntp/sntp-opts.c +++ b/sntp/sntp-opts.c @@ -1,7 +1,7 @@ /* * EDIT THIS FILE WITH CAUTION (sntp-opts.c) * - * It has been AutoGen-ed January 20, 2011 at 11:14:56 AM by AutoGen 5.11.6pre7 + * It has been AutoGen-ed February 7, 2011 at 02:10:40 AM by AutoGen 5.11.6pre20 * From the definitions sntp-opts.def * and the template file options * @@ -26,7 +26,8 @@ #include #include #include - +#include +extern FILE * option_usage_fp; #define OPTION_CODE_COMPILE 1 #include "sntp-opts.h" @@ -45,6 +46,15 @@ tSCC zCopyrightNotice[24] = extern tUsageProc optionUsage; +/* + * global included definitions + */ +#ifdef __windows + extern int atoi(const char*); +#else +# include +#endif + #ifndef NULL # define NULL 0 #endif @@ -55,6 +65,25 @@ extern tUsageProc optionUsage; # define EXIT_FAILURE 1 #endif +/* + * Debug_Level option description: + */ +static char const zDebug_LevelText[] = + "Increase output debug message level"; +static char const zDebug_Level_NAME[] = "DEBUG_LEVEL"; +static char const zDebug_Level_Name[] = "debug-level"; +#define DEBUG_LEVEL_FLAGS (OPTST_DISABLED) + +/* + * Set_Debug_Level option description: + */ +static char const zSet_Debug_LevelText[] = + "Set the output debug message level"; +static char const zSet_Debug_Level_NAME[] = "SET_DEBUG_LEVEL"; +static char const zSet_Debug_Level_Name[] = "set-debug-level"; +#define SET_DEBUG_LEVEL_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + /* * Ipv4 option description with * "Must also have options" and "Incompatible options": @@ -82,13 +111,56 @@ static const int #define IPV6_FLAGS (OPTST_DISABLED) /* - * Normalverbose option description: + * Authentication option description: + */ +static char const zAuthenticationText[] = + "Enable authentication with the key auth-keynumber"; +static char const zAuthentication_NAME[] = "AUTHENTICATION"; +static char const zAuthentication_Name[] = "authentication"; +#define AUTHENTICATION_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/* + * Bctimeout option description: */ -static char const zNormalverboseText[] = - "Normal verbose"; -static char const zNormalverbose_NAME[] = "NORMALVERBOSE"; -static char const zNormalverbose_Name[] = "normalverbose"; -#define NORMALVERBOSE_FLAGS (OPTST_DISABLED) +static char const zBctimeoutText[] = + "The number of seconds to wait for broadcasts"; +static char const zBctimeout_NAME[] = "BCTIMEOUT"; +static char const zBctimeout_Name[] = "bctimeout"; +#define zBctimeoutDefaultArg ((char const*)68) +#define BCTIMEOUT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + +/* + * Broadcast option description: + */ +static char const zBroadcastText[] = + "Listen to the address specified for broadcast time sync"; +static char const zBroadcast_NAME[] = "BROADCAST"; +static char const zBroadcast_Name[] = "broadcast"; +#define BROADCAST_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * Concurrent option description: + */ +static char const zConcurrentText[] = + "Concurrent query all IPs returned for host-name"; +static char const zConcurrent_NAME[] = "CONCURRENT"; +static char const zConcurrent_Name[] = "concurrent"; +#define CONCURRENT_FLAGS (OPTST_DISABLED | OPTST_STACKED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + +/* + * Headspace option description: + */ +static char const zHeadspaceText[] = + "The gap (in milliseconds) between time requests"; +static char const zHeadspace_NAME[] = "HEADSPACE"; +static char const zHeadspace_Name[] = "headspace"; +#define zHeadspaceDefaultArg ((char const*)10) +#define HEADSPACE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) /* * Kod option description: @@ -97,102 +169,99 @@ static char const zKodText[] = "KoD history filename"; static char const zKod_NAME[] = "KOD"; static char const zKod_Name[] = "kod"; +static char const zKodDefaultArg[] = "/var/db/ntp-kod"; #define KOD_FLAGS (OPTST_DISABLED \ - | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + | OPTST_SET_ARGTYPE(OPARG_TYPE_FILE)) /* - * Syslog option description with - * "Must also have options" and "Incompatible options": + * Keyfile option description: */ -static char const zSyslogText[] = - "Logging with syslog"; -static char const zSyslog_NAME[] = "SYSLOG"; -static char const zSyslog_Name[] = "syslog"; -static const int - aSyslogCantList[] = { - INDEX_OPT_FILELOG, NO_EQUIVALENT }; -#define SYSLOG_FLAGS (OPTST_DISABLED) +static char const zKeyfileText[] = + "Look in this file for the key specified with -a"; +static char const zKeyfile_NAME[] = "KEYFILE"; +static char const zKeyfile_Name[] = "keyfile"; +#define KEYFILE_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_FILE)) /* - * Filelog option description with - * "Must also have options" and "Incompatible options": + * Filelog option description: */ static char const zFilelogText[] = "Log to specified logfile"; static char const zFilelog_NAME[] = "FILELOG"; static char const zFilelog_Name[] = "filelog"; -static const int - aFilelogCantList[] = { - INDEX_OPT_SYSLOG, NO_EQUIVALENT }; #define FILELOG_FLAGS (OPTST_DISABLED \ - | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) + | OPTST_SET_ARGTYPE(OPARG_TYPE_FILE)) /* - * Settod option description with - * "Must also have options" and "Incompatible options": + * Steplimit option description: */ -static char const zSettodText[] = - "Set (step) the time with settimeofday()"; -static char const zSettod_NAME[] = "SETTOD"; -static char const zSettod_Name[] = "settod"; -static const int - aSettodCantList[] = { - INDEX_OPT_ADJTIME, NO_EQUIVALENT }; -#define SETTOD_FLAGS (OPTST_DISABLED) +static char const zSteplimitText[] = + "Adjustments less than steplimit msec will be slewed."; +static char const zSteplimit_NAME[] = "STEPLIMIT"; +static char const zSteplimit_Name[] = "steplimit"; +#define STEPLIMIT_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) /* - * Adjtime option description with - * "Must also have options" and "Incompatible options": + * Ntpversion option description: */ -static char const zAdjtimeText[] = - "Set (slew) the time with adjtime()"; -static char const zAdjtime_NAME[] = "ADJTIME"; -static char const zAdjtime_Name[] = "adjtime"; -static const int - aAdjtimeCantList[] = { - INDEX_OPT_SETTOD, NO_EQUIVALENT }; -#define ADJTIME_FLAGS (OPTST_DISABLED) +static char const zNtpversionText[] = + "Send as our NTP version"; +static char const zNtpversion_NAME[] = "NTPVERSION"; +static char const zNtpversion_Name[] = "ntpversion"; +#define zNtpversionDefaultArg ((char const*)4) +#define NTPVERSION_FLAGS (OPTST_DISABLED \ + | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) /* - * Broadcast option description: + * Usereservedport option description: */ -static char const zBroadcastText[] = - "Use broadcasts to the address specified for synchronisation"; -static char const zBroadcast_NAME[] = "BROADCAST"; -static char const zBroadcast_Name[] = "broadcast"; -#define BROADCAST_FLAGS (OPTST_DISABLED \ - | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) +static char const zUsereservedportText[] = + "Use the NTP Reserved Port (port 123)"; +static char const zUsereservedport_NAME[] = "USERESERVEDPORT"; +static char const zUsereservedport_Name[] = "usereservedport"; +#define USERESERVEDPORT_FLAGS (OPTST_DISABLED) /* - * Timeout option description: - */ -static char const zTimeoutText[] = - "Specify the number of seconds to wait for broadcasts"; -static char const zTimeout_NAME[] = "TIMEOUT"; -static char const zTimeout_Name[] = "timeout"; -#define zTimeoutDefaultArg ((char const*)68) -#define TIMEOUT_FLAGS (OPTST_DISABLED \ - | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) + * Step option description: + */ +static char const zStepText[] = + "OK to 'step' the time with settimeofday()"; +static char const zStep_NAME[] = "STEP"; +static char const zStep_Name[] = "step"; +#define STEP_FLAGS (OPTST_DISABLED) /* - * Authentication option description: + * Slew option description: */ -static char const zAuthenticationText[] = - "Enable authentication with the key auth-keynumber"; -static char const zAuthentication_NAME[] = "AUTHENTICATION"; -static char const zAuthentication_Name[] = "authentication"; -#define AUTHENTICATION_FLAGS (OPTST_DISABLED \ +static char const zSlewText[] = + "OK to 'slew' the time with adjtime()"; +static char const zSlew_NAME[] = "SLEW"; +static char const zSlew_Name[] = "slew"; +#define SLEW_FLAGS (OPTST_DISABLED) + +/* + * Uctimeout option description: + */ +static char const zUctimeoutText[] = + "The number of seconds to wait for unicast responses"; +static char const zUctimeout_NAME[] = "UCTIMEOUT"; +static char const zUctimeout_Name[] = "uctimeout"; +#define zUctimeoutDefaultArg ((char const*)5) +#define UCTIMEOUT_FLAGS (OPTST_DISABLED \ | OPTST_SET_ARGTYPE(OPARG_TYPE_NUMERIC)) /* - * Keyfile option description: + * Wait option description: */ -static char const zKeyfileText[] = - "Specify a keyfile. SNTP will look in this file for the key specified with -a"; -static char const zKeyfile_NAME[] = "KEYFILE"; -static char const zKeyfile_Name[] = "keyfile"; -#define KEYFILE_FLAGS (OPTST_DISABLED \ - | OPTST_SET_ARGTYPE(OPARG_TYPE_STRING)) +static char const zWaitText[] = + "Wait for pending replies (if not setting the time)"; +static char const zWait_NAME[] = "WAIT"; +static char const zNotWait_Name[] = "no-wait"; +static char const zNotWait_Pfx[] = "no"; +#define zWait_Name (zNotWait_Name + 3) +#define WAIT_FLAGS (OPTST_INITENABLED) /* * Help/More_Help/Version option descriptions: @@ -233,7 +302,14 @@ static char const zNotLoad_Opts_Pfx[] = "no"; * if multiple copies are allowed. */ static tOptProc - doUsageOpt; + doOptFilelog, doOptKeyfile, doOptKod, doOptNtpversion, + doOptSteplimit, doUsageOpt; + +/* + * #define map the "normal" callout procs to the test ones... + */ +#define SET_DEBUG_LEVEL_OPT_PROC optionStackArg + #else /* NOT defined TEST_SNTP_OPTS */ /* @@ -245,7 +321,16 @@ extern tOptProc optionStackArg, optionTimeVal, optionUnstackArg, optionVersionStderr; static tOptProc + doOptFilelog, doOptKeyfile, doOptKod, + doOptNtpversion, doOptSet_Debug_Level, doOptSteplimit, doUsageOpt; + +/* + * #define map the "normal" callout procs + */ +#define SET_DEBUG_LEVEL_OPT_PROC doOptSet_Debug_Level + +#define SET_DEBUG_LEVEL_OPT_PROC doOptSet_Debug_Level #endif /* defined(TEST_SNTP_OPTS) */ #ifdef TEST_SNTP_OPTS # define DOVERPROC optionVersionStderr @@ -258,8 +343,32 @@ static tOptProc * Define the Sntp Option Descriptions. */ static tOptDesc optDesc[ OPTION_CT ] = { - { /* entry idx, value */ 0, VALUE_OPT_IPV4, - /* equiv idx, value */ 0, VALUE_OPT_IPV4, + { /* entry idx, value */ 0, VALUE_OPT_DEBUG_LEVEL, + /* equiv idx, value */ 0, VALUE_OPT_DEBUG_LEVEL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ DEBUG_LEVEL_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ NULL, + /* desc, NAME, name */ zDebug_LevelText, zDebug_Level_NAME, zDebug_Level_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 1, VALUE_OPT_SET_DEBUG_LEVEL, + /* equiv idx, value */ 1, VALUE_OPT_SET_DEBUG_LEVEL, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ SET_DEBUG_LEVEL_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ SET_DEBUG_LEVEL_OPT_PROC, + /* desc, NAME, name */ zSet_Debug_LevelText, zSet_Debug_Level_NAME, zSet_Debug_Level_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 2, VALUE_OPT_IPV4, + /* equiv idx, value */ 2, VALUE_OPT_IPV4, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ IPV4_FLAGS, 0, @@ -270,8 +379,8 @@ static tOptDesc optDesc[ OPTION_CT ] = { /* desc, NAME, name */ zIpv4Text, zIpv4_NAME, zIpv4_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 1, VALUE_OPT_IPV6, - /* equiv idx, value */ 1, VALUE_OPT_IPV6, + { /* entry idx, value */ 3, VALUE_OPT_IPV6, + /* equiv idx, value */ 3, VALUE_OPT_IPV6, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ IPV6_FLAGS, 0, @@ -282,125 +391,185 @@ static tOptDesc optDesc[ OPTION_CT ] = { /* desc, NAME, name */ zIpv6Text, zIpv6_NAME, zIpv6_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 2, VALUE_OPT_NORMALVERBOSE, - /* equiv idx, value */ 2, VALUE_OPT_NORMALVERBOSE, + { /* entry idx, value */ 4, VALUE_OPT_AUTHENTICATION, + /* equiv idx, value */ 4, VALUE_OPT_AUTHENTICATION, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ NORMALVERBOSE_FLAGS, 0, + /* opt state flags */ AUTHENTICATION_FLAGS, 0, /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, /* must/cannot opts */ NULL, NULL, - /* option proc */ NULL, - /* desc, NAME, name */ zNormalverboseText, zNormalverbose_NAME, zNormalverbose_Name, + /* option proc */ optionNumericVal, + /* desc, NAME, name */ zAuthenticationText, zAuthentication_NAME, zAuthentication_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 3, VALUE_OPT_KOD, - /* equiv idx, value */ 3, VALUE_OPT_KOD, + { /* entry idx, value */ 5, VALUE_OPT_BCTIMEOUT, + /* equiv idx, value */ 5, VALUE_OPT_BCTIMEOUT, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ KOD_FLAGS, 0, + /* opt state flags */ BCTIMEOUT_FLAGS, 0, + /* last opt argumnt */ { zBctimeoutDefaultArg }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionNumericVal, + /* desc, NAME, name */ zBctimeoutText, zBctimeout_NAME, zBctimeout_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 6, VALUE_OPT_BROADCAST, + /* equiv idx, value */ 6, VALUE_OPT_BROADCAST, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ BROADCAST_FLAGS, 0, /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, /* must/cannot opts */ NULL, NULL, - /* option proc */ NULL, + /* option proc */ optionStackArg, + /* desc, NAME, name */ zBroadcastText, zBroadcast_NAME, zBroadcast_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 7, VALUE_OPT_CONCURRENT, + /* equiv idx, value */ 7, VALUE_OPT_CONCURRENT, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, NOLIMIT, 0, + /* opt state flags */ CONCURRENT_FLAGS, 0, + /* last opt argumnt */ { NULL }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionStackArg, + /* desc, NAME, name */ zConcurrentText, zConcurrent_NAME, zConcurrent_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 8, VALUE_OPT_HEADSPACE, + /* equiv idx, value */ 8, VALUE_OPT_HEADSPACE, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ HEADSPACE_FLAGS, 0, + /* last opt argumnt */ { zHeadspaceDefaultArg }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ optionNumericVal, + /* desc, NAME, name */ zHeadspaceText, zHeadspace_NAME, zHeadspace_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 9, VALUE_OPT_KOD, + /* equiv idx, value */ 9, VALUE_OPT_KOD, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ KOD_FLAGS, 0, + /* last opt argumnt */ { zKodDefaultArg }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptKod, /* desc, NAME, name */ zKodText, zKod_NAME, zKod_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 4, VALUE_OPT_SYSLOG, - /* equiv idx, value */ 4, VALUE_OPT_SYSLOG, + { /* entry idx, value */ 10, VALUE_OPT_KEYFILE, + /* equiv idx, value */ 10, VALUE_OPT_KEYFILE, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ SYSLOG_FLAGS, 0, + /* opt state flags */ KEYFILE_FLAGS, 0, /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, aSyslogCantList, - /* option proc */ NULL, - /* desc, NAME, name */ zSyslogText, zSyslog_NAME, zSyslog_Name, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptKeyfile, + /* desc, NAME, name */ zKeyfileText, zKeyfile_NAME, zKeyfile_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 5, VALUE_OPT_FILELOG, - /* equiv idx, value */ 5, VALUE_OPT_FILELOG, + { /* entry idx, value */ 11, VALUE_OPT_FILELOG, + /* equiv idx, value */ 11, VALUE_OPT_FILELOG, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, /* opt state flags */ FILELOG_FLAGS, 0, /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, aFilelogCantList, - /* option proc */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptFilelog, /* desc, NAME, name */ zFilelogText, zFilelog_NAME, zFilelog_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 6, VALUE_OPT_SETTOD, - /* equiv idx, value */ 6, VALUE_OPT_SETTOD, + { /* entry idx, value */ 12, VALUE_OPT_STEPLIMIT, + /* equiv idx, value */ 12, VALUE_OPT_STEPLIMIT, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ SETTOD_FLAGS, 0, + /* opt state flags */ STEPLIMIT_FLAGS, 0, /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, aSettodCantList, - /* option proc */ NULL, - /* desc, NAME, name */ zSettodText, zSettod_NAME, zSettod_Name, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptSteplimit, + /* desc, NAME, name */ zSteplimitText, zSteplimit_NAME, zSteplimit_Name, + /* disablement strs */ NULL, NULL }, + + { /* entry idx, value */ 13, VALUE_OPT_NTPVERSION, + /* equiv idx, value */ 13, VALUE_OPT_NTPVERSION, + /* equivalenced to */ NO_EQUIVALENT, + /* min, max, act ct */ 0, 1, 0, + /* opt state flags */ NTPVERSION_FLAGS, 0, + /* last opt argumnt */ { zNtpversionDefaultArg }, + /* arg list/cookie */ NULL, + /* must/cannot opts */ NULL, NULL, + /* option proc */ doOptNtpversion, + /* desc, NAME, name */ zNtpversionText, zNtpversion_NAME, zNtpversion_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 7, VALUE_OPT_ADJTIME, - /* equiv idx, value */ 7, VALUE_OPT_ADJTIME, + { /* entry idx, value */ 14, VALUE_OPT_USERESERVEDPORT, + /* equiv idx, value */ 14, VALUE_OPT_USERESERVEDPORT, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ ADJTIME_FLAGS, 0, + /* opt state flags */ USERESERVEDPORT_FLAGS, 0, /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, - /* must/cannot opts */ NULL, aAdjtimeCantList, + /* must/cannot opts */ NULL, NULL, /* option proc */ NULL, - /* desc, NAME, name */ zAdjtimeText, zAdjtime_NAME, zAdjtime_Name, + /* desc, NAME, name */ zUsereservedportText, zUsereservedport_NAME, zUsereservedport_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 8, VALUE_OPT_BROADCAST, - /* equiv idx, value */ 8, VALUE_OPT_BROADCAST, + { /* entry idx, value */ 15, VALUE_OPT_STEP, + /* equiv idx, value */ 15, VALUE_OPT_STEP, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ BROADCAST_FLAGS, 0, + /* opt state flags */ STEP_FLAGS, 0, /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, /* must/cannot opts */ NULL, NULL, /* option proc */ NULL, - /* desc, NAME, name */ zBroadcastText, zBroadcast_NAME, zBroadcast_Name, + /* desc, NAME, name */ zStepText, zStep_NAME, zStep_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 9, VALUE_OPT_TIMEOUT, - /* equiv idx, value */ 9, VALUE_OPT_TIMEOUT, + { /* entry idx, value */ 16, VALUE_OPT_SLEW, + /* equiv idx, value */ 16, VALUE_OPT_SLEW, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ TIMEOUT_FLAGS, 0, - /* last opt argumnt */ { zTimeoutDefaultArg }, + /* opt state flags */ SLEW_FLAGS, 0, + /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, /* must/cannot opts */ NULL, NULL, - /* option proc */ optionNumericVal, - /* desc, NAME, name */ zTimeoutText, zTimeout_NAME, zTimeout_Name, + /* option proc */ NULL, + /* desc, NAME, name */ zSlewText, zSlew_NAME, zSlew_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 10, VALUE_OPT_AUTHENTICATION, - /* equiv idx, value */ 10, VALUE_OPT_AUTHENTICATION, + { /* entry idx, value */ 17, VALUE_OPT_UCTIMEOUT, + /* equiv idx, value */ 17, VALUE_OPT_UCTIMEOUT, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ AUTHENTICATION_FLAGS, 0, - /* last opt argumnt */ { NULL }, + /* opt state flags */ UCTIMEOUT_FLAGS, 0, + /* last opt argumnt */ { zUctimeoutDefaultArg }, /* arg list/cookie */ NULL, /* must/cannot opts */ NULL, NULL, /* option proc */ optionNumericVal, - /* desc, NAME, name */ zAuthenticationText, zAuthentication_NAME, zAuthentication_Name, + /* desc, NAME, name */ zUctimeoutText, zUctimeout_NAME, zUctimeout_Name, /* disablement strs */ NULL, NULL }, - { /* entry idx, value */ 11, VALUE_OPT_KEYFILE, - /* equiv idx, value */ 11, VALUE_OPT_KEYFILE, + { /* entry idx, value */ 18, VALUE_OPT_WAIT, + /* equiv idx, value */ 18, VALUE_OPT_WAIT, /* equivalenced to */ NO_EQUIVALENT, /* min, max, act ct */ 0, 1, 0, - /* opt state flags */ KEYFILE_FLAGS, 0, + /* opt state flags */ WAIT_FLAGS, 0, /* last opt argumnt */ { NULL }, /* arg list/cookie */ NULL, /* must/cannot opts */ NULL, NULL, /* option proc */ NULL, - /* desc, NAME, name */ zKeyfileText, zKeyfile_NAME, zKeyfile_Name, - /* disablement strs */ NULL, NULL }, + /* desc, NAME, name */ zWaitText, zWait_NAME, zWait_Name, + /* disablement strs */ zNotWait_Name, zNotWait_Pfx }, { /* entry idx, value */ INDEX_OPT_VERSION, VALUE_OPT_VERSION, /* equiv idx value */ NO_EQUIVALENT, 0, @@ -472,9 +641,10 @@ static tOptDesc optDesc[ OPTION_CT ] = { * Define the Sntp Option Environment */ static char const zPROGNAME[5] = "SNTP"; -static char const zUsageTitle[123] = -"sntp - standard SNTP program - Ver. 4.2.7p120\n\ -USAGE: %s [ - [] | --[{=| }] ]... hostname-or-IP ...\n"; +static char const zUsageTitle[154] = +"sntp - standard Simple Network Time Protocol program - Ver. 4.2.7p120\n\ +USAGE: %s [ - [] | --[{=| }] ]... \\\n\ +\t\t[ hostname-or-IP ...]\n"; static char const zRcName[7] = ".ntprc"; static char const * const apzHomeList[3] = { "$HOME", @@ -483,15 +653,15 @@ static char const * const apzHomeList[3] = { static char const zBugsAddr[34] = "http://bugs.ntp.org, bugs@ntp.org"; static char const zExplain[] = "\n\n"; -static char const zDetail[352] = "\n\ -sntp implements the Simple Network Time Protocol, and is used to query\n\ -an NTP or SNTP server and either display the time or set the local\n\ -system's time (given suitable privilege).\n\n\ +static char const zDetail[351] = "\n\ +sntp implements the Simple Network Time Protocol and is used to query an\n\ +NTP or SNTP server and either display the time or set the local system's\n\ +time (given suitable privilege).\n\n\ It can be run interactively from the command line or as a cron job.\n\n\ -NTP and SNTP are defined by RFC 5905, which obsoletes RFC 4330 and RFC\n\ -1305.\n"; +NTP and SNTP are defined by RFC 5905, which obsoletes RFC 4330 and\n\ +RFC 1305.\n"; static char const zFullVersion[] = SNTP_FULL_VERSION; -/* extracted from /usr/local/gnu/share/autogen/optcode.tpl near line 504 */ +/* extracted from /usr/local/share/autogen/optcode.tlib near line 504 */ #if defined(ENABLE_NLS) # define OPTPROC_BASE OPTPROC_TRANSLATE @@ -508,6 +678,22 @@ static char const zFullVersion[] = SNTP_FULL_VERSION; # define PKGDATADIR "" #endif +#ifndef WITH_PACKAGER +# define sntp_packager_info NULL +#else +static char const sntp_packager_info[] = + "Packaged by " WITH_PACKAGER + +# ifdef WITH_PACKAGER_VERSION + " ("WITH_PACKAGER_VERSION")" +# endif + +# ifdef WITH_PACKAGER_BUG_REPORTS + "\nReport sntp bugs to " WITH_PACKAGER_BUG_REPORTS +# endif + "\n"; +#endif + tOptions sntpOptions = { OPTIONS_STRUCT_VERSION, 0, NULL, /* original argc + argv */ @@ -516,8 +702,8 @@ tOptions sntpOptions = { + OPTPROC_SHORTOPT + OPTPROC_LONGOPT + OPTPROC_NO_REQ_OPT + + OPTPROC_NEGATIONS + OPTPROC_ENVIRON - + OPTPROC_ARGS_REQ + OPTPROC_MISUSE ), 0, NULL, /* current option index, current option */ NULL, NULL, zPROGNAME, @@ -526,7 +712,7 @@ tOptions sntpOptions = { zExplain, zDetail, optDesc, zBugsAddr, /* address to send bugs to */ NULL, NULL, /* extensions/saved state */ - optionUsage, /* usage procedure */ + optionUsage, /* usage procedure */ translate_option_strings, /* translation procedure */ /* * Indexes to special options @@ -536,10 +722,10 @@ tOptions sntpOptions = { NO_EQUIVALENT, /* '-#' option index */ NO_EQUIVALENT /* index of default opt */ }, - 17 /* full option count */, 12 /* user option count */, + 24 /* full option count */, 19 /* user option count */, sntp_full_usage, sntp_short_usage, NULL, NULL, - PKGDATADIR + PKGDATADIR, sntp_packager_info }; /* @@ -553,7 +739,175 @@ doUsageOpt( (void)pOptions; USAGE(EXIT_SUCCESS); } -/* extracted from /usr/local/gnu/share/autogen/optmain.tpl near line 107 */ + +#if ! defined(TEST_SNTP_OPTS) + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * For the set-debug-level option. + */ +static void +doOptSet_Debug_Level(tOptions* pOptions, tOptDesc* pOptDesc) +{ + /* extracted from include/debug-opt.def, line 27 */ +DESC(DEBUG_LEVEL).optOccCt = atoi( pOptDesc->pzLastArg ); +} +#endif /* defined(TEST_SNTP_OPTS) */ + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * For the kod option. + */ +static void +doOptKod(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static teOptFileType const type = + FTYPE_MODE_MAY_EXIST + FTYPE_MODE_NO_OPEN; + static tuFileMode mode; +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif + mode.file_flags = O_CLOEXEC; + + optionFileCheck(pOptions, pOptDesc, type, mode); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * For the keyfile option. + */ +static void +doOptKeyfile(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static teOptFileType const type = + FTYPE_MODE_MAY_EXIST + FTYPE_MODE_NO_OPEN; + static tuFileMode mode; +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif + mode.file_flags = O_CLOEXEC; + + optionFileCheck(pOptions, pOptDesc, type, mode); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * For the filelog option. + */ +static void +doOptFilelog(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static teOptFileType const type = + FTYPE_MODE_MAY_EXIST + FTYPE_MODE_NO_OPEN; + static tuFileMode mode; +#ifndef O_CLOEXEC +# define O_CLOEXEC 0 +#endif + mode.file_flags = O_CLOEXEC; + + optionFileCheck(pOptions, pOptDesc, type, mode); +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * For the steplimit option. + */ +static void +doOptSteplimit(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static const struct {long const rmin, rmax;} rng[1] = { + { 0, LONG_MAX } }; + long val; + int ix; + char * pzEnd; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + + errno = 0; + val = strtol(pOptDesc->optArg.argString, &pzEnd, 0); + if ((pOptDesc->optArg.argString == pzEnd) || (errno != 0)) + goto bad_value; + + if (*pzEnd != '\0') + goto bad_value; + for (ix = 0; ix < 1; ix++) { + if (val < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (val == rng[ix].rmin) + goto valid_return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (val <= rng[ix].rmax) + goto valid_return; + } + + bad_value: + + option_usage_fp = stderr; + + emit_ranges: + optionShowRange(pOptions, pOptDesc, (void *)rng, 1); + return; + + valid_return: + if ((pOptDesc->fOptState & OPTST_ALLOC_ARG) != 0) { + free((void *)pOptDesc->optArg.argString); + pOptDesc->fOptState &= ~OPTST_ALLOC_ARG; + } + pOptDesc->optArg.argInt = val; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * + * For the ntpversion option. + */ +static void +doOptNtpversion(tOptions* pOptions, tOptDesc* pOptDesc) +{ + static const struct {long const rmin, rmax;} rng[1] = { + { 0, 7 } }; + long val; + int ix; + char * pzEnd; + + if (pOptions <= OPTPROC_EMIT_LIMIT) + goto emit_ranges; + + errno = 0; + val = strtol(pOptDesc->optArg.argString, &pzEnd, 0); + if ((pOptDesc->optArg.argString == pzEnd) || (errno != 0)) + goto bad_value; + + if (*pzEnd != '\0') + goto bad_value; + for (ix = 0; ix < 1; ix++) { + if (val < rng[ix].rmin) + continue; /* ranges need not be ordered. */ + if (val == rng[ix].rmin) + goto valid_return; + if (rng[ix].rmax == LONG_MIN) + continue; + if (val <= rng[ix].rmax) + goto valid_return; + } + + bad_value: + + option_usage_fp = stderr; + + emit_ranges: + optionShowRange(pOptions, pOptDesc, (void *)rng, 1); + return; + + valid_return: + if ((pOptDesc->fOptState & OPTST_ALLOC_ARG) != 0) { + free((void *)pOptDesc->optArg.argString); + pOptDesc->fOptState &= ~OPTST_ALLOC_ARG; + } + pOptDesc->optArg.argInt = val; +} +/* extracted from /usr/local/share/autogen/optmain.tlib near line 107 */ #if defined(TEST_SNTP_OPTS) /* TEST MAIN PROCEDURE: */ @@ -571,7 +925,7 @@ main(int argc, char** argv) return res; } #endif /* defined TEST_SNTP_OPTS */ -/* extracted from /usr/local/gnu/share/autogen/optcode.tpl near line 641 */ +/* extracted from /usr/local/share/autogen/optcode.tlib near line 657 */ #if ENABLE_NLS #include @@ -615,7 +969,6 @@ translate_option_strings(void) * been changed by the first pass through this code. One shot only. */ if (option_usage_text.field_ct != 0) { - /* * Do the translations. The first pointer follows the field count * field. The field count field is the size of a pointer. @@ -635,6 +988,7 @@ translate_option_strings(void) COERSION(pzUsageTitle); COERSION(pzExplain); COERSION(pzDetail); + COERSION(pzPackager); option_usage_text.field_ct = 0; for (ix = sntpOptions.optCt; ix > 0; ix--, pOD++) diff --git a/sntp/sntp-opts.def b/sntp/sntp-opts.def index 64bbb6c03..309f9be20 100644 --- a/sntp/sntp-opts.def +++ b/sntp/sntp-opts.def @@ -7,7 +7,7 @@ autogen definitions options; #include debug-opt.def prog-name = "sntp"; -prog-title = "standard SNTP program"; +prog-title = "standard Simple Network Time Protocol program"; homerc = $HOME, "."; argument = '[ hostname-or-IP ...]'; @@ -65,7 +65,7 @@ flag = { flag = { name = bctimeout; value = B; - descrip = "Specify the number of seconds to wait for broadcasts"; + descrip = "The number of seconds to wait for broadcasts"; arg-type = number; arg-name = "seconds"; arg-default = 68; @@ -112,14 +112,18 @@ flag = { }; flag = { - name = filelog; - value = l; - arg-type = file; - arg-name = "file-name"; - descrip = "Log to specified logfile"; - doc = <<- _EndOfDoc_ - This option causes the client to write log messages to the specified - logfile. + name = headspace; + value = h; + descrip = "The gap (in milliseconds) between time requests"; + arg-type = number; + arg-name = "milliseconds"; + arg-default = 10; + doc = <<- _EndOfDoc_ + Since we're only going to use the first valid response we get and + there is benefit to specifying a good number of servers to query, + separate the queries we send out by the specified number of + milliseconds. + Default 10 milliseconds. _EndOfDoc_; }; @@ -140,7 +144,7 @@ flag = { flag = { name = keyfile; value = k; - descrip = "Specify a keyfile. SNTP will look in this file for the key specified with -a"; + descrip = "Look in this file for the key specified with -a"; arg-type = file; arg-name = "file-name"; doc = <<- _EndOfDoc_ @@ -160,6 +164,18 @@ flag = { _EndOfDoc_; }; +flag = { + name = filelog; + value = l; + arg-type = file; + arg-name = "file-name"; + descrip = "Log to specified logfile"; + doc = <<- _EndOfDoc_ + This option causes the client to write log messages to the specified + logfile. + _EndOfDoc_; +}; + flag = { name = steplimit; value = M; @@ -210,6 +226,30 @@ flag = { }; +flag = { + name = uctimeout; + value = u; + descrip = "The number of seconds to wait for unicast responses"; + arg-type = number; + arg-name = "seconds"; + arg-default = 5; + doc = <<- _EndOfDoc_ + When waiting for a unicast reply, SNTP will wait the number + of seconds specified before giving up. Default 5 seconds. + _EndOfDoc_; +}; + +flag = { + name = "wait"; + descrip = "Wait for pending replies (if not setting the time)"; + disable = no; + enabled; + settable; + doc = <<- _EndOfDoc_ + If we are not setting the time, wait for all pending responses. + _EndOfDoc_; +}; + /* explain: Additional information whenever the usage routine is invoked */ explain = <<- _END_EXPLAIN _END_EXPLAIN; diff --git a/sntp/sntp-opts.h b/sntp/sntp-opts.h index f7c29504e..abdc7005e 100644 --- a/sntp/sntp-opts.h +++ b/sntp/sntp-opts.h @@ -1,7 +1,7 @@ /* * EDIT THIS FILE WITH CAUTION (sntp-opts.h) * - * It has been AutoGen-ed January 20, 2011 at 11:14:55 AM by AutoGen 5.11.6pre7 + * It has been AutoGen-ed February 7, 2011 at 02:10:40 AM by AutoGen 5.11.6pre20 * From the definitions sntp-opts.def * and the template file options * @@ -50,33 +50,40 @@ * Enumeration of each option: */ typedef enum { - INDEX_OPT_IPV4 = 0, - INDEX_OPT_IPV6 = 1, - INDEX_OPT_NORMALVERBOSE = 2, - INDEX_OPT_KOD = 3, - INDEX_OPT_SYSLOG = 4, - INDEX_OPT_FILELOG = 5, - INDEX_OPT_SETTOD = 6, - INDEX_OPT_ADJTIME = 7, - INDEX_OPT_BROADCAST = 8, - INDEX_OPT_TIMEOUT = 9, - INDEX_OPT_AUTHENTICATION = 10, - INDEX_OPT_KEYFILE = 11, - INDEX_OPT_VERSION = 12, - INDEX_OPT_HELP = 13, - INDEX_OPT_MORE_HELP = 14, - INDEX_OPT_SAVE_OPTS = 15, - INDEX_OPT_LOAD_OPTS = 16 + INDEX_OPT_DEBUG_LEVEL = 0, + INDEX_OPT_SET_DEBUG_LEVEL = 1, + INDEX_OPT_IPV4 = 2, + INDEX_OPT_IPV6 = 3, + INDEX_OPT_AUTHENTICATION = 4, + INDEX_OPT_BCTIMEOUT = 5, + INDEX_OPT_BROADCAST = 6, + INDEX_OPT_CONCURRENT = 7, + INDEX_OPT_HEADSPACE = 8, + INDEX_OPT_KOD = 9, + INDEX_OPT_KEYFILE = 10, + INDEX_OPT_FILELOG = 11, + INDEX_OPT_STEPLIMIT = 12, + INDEX_OPT_NTPVERSION = 13, + INDEX_OPT_USERESERVEDPORT = 14, + INDEX_OPT_STEP = 15, + INDEX_OPT_SLEW = 16, + INDEX_OPT_UCTIMEOUT = 17, + INDEX_OPT_WAIT = 18, + INDEX_OPT_VERSION = 19, + INDEX_OPT_HELP = 20, + INDEX_OPT_MORE_HELP = 21, + INDEX_OPT_SAVE_OPTS = 22, + INDEX_OPT_LOAD_OPTS = 23 } teOptIndex; -#define OPTION_CT 17 +#define OPTION_CT 24 #define SNTP_VERSION "4.2.7p120" -#define SNTP_FULL_VERSION "sntp - standard SNTP program - Ver. 4.2.7p120" +#define SNTP_FULL_VERSION "sntp - standard Simple Network Time Protocol program - Ver. 4.2.7p120" /* * Interface defines for all options. Replace "n" with the UPPER_CASED * option name (as in the teOptIndex enumeration above). - * e.g. HAVE_OPT(IPV4) + * e.g. HAVE_OPT(DEBUG_LEVEL) */ #define DESC(n) (sntpOptions.pOptDesc[INDEX_OPT_## n]) #define HAVE_OPT(n) (! UNUSED_OPT(& DESC(n))) @@ -107,6 +114,14 @@ typedef enum { * Make sure there are no #define name conflicts with the option names */ #ifndef NO_OPTION_NAME_WARNINGS +# ifdef DEBUG_LEVEL +# warning undefining DEBUG_LEVEL due to option name conflict +# undef DEBUG_LEVEL +# endif +# ifdef SET_DEBUG_LEVEL +# warning undefining SET_DEBUG_LEVEL due to option name conflict +# undef SET_DEBUG_LEVEL +# endif # ifdef IPV4 # warning undefining IPV4 due to option name conflict # undef IPV4 @@ -115,81 +130,133 @@ typedef enum { # warning undefining IPV6 due to option name conflict # undef IPV6 # endif -# ifdef NORMALVERBOSE -# warning undefining NORMALVERBOSE due to option name conflict -# undef NORMALVERBOSE +# ifdef AUTHENTICATION +# warning undefining AUTHENTICATION due to option name conflict +# undef AUTHENTICATION +# endif +# ifdef BCTIMEOUT +# warning undefining BCTIMEOUT due to option name conflict +# undef BCTIMEOUT +# endif +# ifdef BROADCAST +# warning undefining BROADCAST due to option name conflict +# undef BROADCAST +# endif +# ifdef CONCURRENT +# warning undefining CONCURRENT due to option name conflict +# undef CONCURRENT +# endif +# ifdef HEADSPACE +# warning undefining HEADSPACE due to option name conflict +# undef HEADSPACE # endif # ifdef KOD # warning undefining KOD due to option name conflict # undef KOD # endif -# ifdef SYSLOG -# warning undefining SYSLOG due to option name conflict -# undef SYSLOG +# ifdef KEYFILE +# warning undefining KEYFILE due to option name conflict +# undef KEYFILE # endif # ifdef FILELOG # warning undefining FILELOG due to option name conflict # undef FILELOG # endif -# ifdef SETTOD -# warning undefining SETTOD due to option name conflict -# undef SETTOD +# ifdef STEPLIMIT +# warning undefining STEPLIMIT due to option name conflict +# undef STEPLIMIT # endif -# ifdef ADJTIME -# warning undefining ADJTIME due to option name conflict -# undef ADJTIME +# ifdef NTPVERSION +# warning undefining NTPVERSION due to option name conflict +# undef NTPVERSION # endif -# ifdef BROADCAST -# warning undefining BROADCAST due to option name conflict -# undef BROADCAST +# ifdef USERESERVEDPORT +# warning undefining USERESERVEDPORT due to option name conflict +# undef USERESERVEDPORT # endif -# ifdef TIMEOUT -# warning undefining TIMEOUT due to option name conflict -# undef TIMEOUT +# ifdef STEP +# warning undefining STEP due to option name conflict +# undef STEP # endif -# ifdef AUTHENTICATION -# warning undefining AUTHENTICATION due to option name conflict -# undef AUTHENTICATION +# ifdef SLEW +# warning undefining SLEW due to option name conflict +# undef SLEW # endif -# ifdef KEYFILE -# warning undefining KEYFILE due to option name conflict -# undef KEYFILE +# ifdef UCTIMEOUT +# warning undefining UCTIMEOUT due to option name conflict +# undef UCTIMEOUT +# endif +# ifdef WAIT +# warning undefining WAIT due to option name conflict +# undef WAIT # endif #else /* NO_OPTION_NAME_WARNINGS */ +# undef DEBUG_LEVEL +# undef SET_DEBUG_LEVEL # undef IPV4 # undef IPV6 -# undef NORMALVERBOSE -# undef KOD -# undef SYSLOG -# undef FILELOG -# undef SETTOD -# undef ADJTIME -# undef BROADCAST -# undef TIMEOUT # undef AUTHENTICATION +# undef BCTIMEOUT +# undef BROADCAST +# undef CONCURRENT +# undef HEADSPACE +# undef KOD # undef KEYFILE +# undef FILELOG +# undef STEPLIMIT +# undef NTPVERSION +# undef USERESERVEDPORT +# undef STEP +# undef SLEW +# undef UCTIMEOUT +# undef WAIT #endif /* NO_OPTION_NAME_WARNINGS */ /* * * * * * * * Interface defines for specific options. */ +#define VALUE_OPT_DEBUG_LEVEL 'd' +#define VALUE_OPT_SET_DEBUG_LEVEL 'D' #define VALUE_OPT_IPV4 '4' #define VALUE_OPT_IPV6 '6' -#define VALUE_OPT_NORMALVERBOSE 'd' -#define VALUE_OPT_KOD 'K' -#define VALUE_OPT_SYSLOG 'p' -#define VALUE_OPT_FILELOG 'l' -#define VALUE_OPT_SETTOD 's' -#define VALUE_OPT_ADJTIME 'j' -#define VALUE_OPT_BROADCAST 'b' -#define VALUE_OPT_TIMEOUT 't' - -#define OPT_VALUE_TIMEOUT (DESC(TIMEOUT).optArg.argInt) #define VALUE_OPT_AUTHENTICATION 'a' #define OPT_VALUE_AUTHENTICATION (DESC(AUTHENTICATION).optArg.argInt) +#define VALUE_OPT_BCTIMEOUT 'B' + +#define OPT_VALUE_BCTIMEOUT (DESC(BCTIMEOUT).optArg.argInt) +#define VALUE_OPT_BROADCAST 'b' +#define VALUE_OPT_CONCURRENT 'c' +#define VALUE_OPT_HEADSPACE 'h' + +#define OPT_VALUE_HEADSPACE (DESC(HEADSPACE).optArg.argInt) +#define VALUE_OPT_KOD 'K' #define VALUE_OPT_KEYFILE 'k' +#define VALUE_OPT_FILELOG 'l' +#define VALUE_OPT_STEPLIMIT 'M' + +#define OPT_VALUE_STEPLIMIT (DESC(STEPLIMIT).optArg.argInt) +#define VALUE_OPT_NTPVERSION 'o' + +#define OPT_VALUE_NTPVERSION (DESC(NTPVERSION).optArg.argInt) +#define VALUE_OPT_USERESERVEDPORT 'r' +#define VALUE_OPT_STEP 'S' +#define VALUE_OPT_SLEW 's' +#define VALUE_OPT_UCTIMEOUT 'u' + +#define OPT_VALUE_UCTIMEOUT (DESC(UCTIMEOUT).optArg.argInt) +#define VALUE_OPT_WAIT 18 + +#define SET_OPT_WAIT STMTS( \ + DESC(WAIT).optActualIndex = 18; \ + DESC(WAIT).optActualValue = VALUE_OPT_WAIT; \ + DESC(WAIT).fOptState &= OPTST_PERSISTENT_MASK; \ + DESC(WAIT).fOptState |= OPTST_SET ) +#define DISABLE_OPT_WAIT STMTS( \ + DESC(WAIT).fOptState &= OPTST_PERSISTENT_MASK; \ + DESC(WAIT).fOptState |= OPTST_SET | OPTST_DISABLED; \ + DESC(WAIT).optArg.argString = NULL ) #define VALUE_OPT_HELP '?' #define VALUE_OPT_MORE_HELP '!' #define VALUE_OPT_VERSION INDEX_OPT_VERSION @@ -209,7 +276,7 @@ typedef enum { sntpOptions.pzCurOpt = NULL) #define START_OPT RESTART_OPT(1) #define USAGE(c) (*sntpOptions.pUsageProc)(&sntpOptions, c) -/* extracted from /usr/local/gnu/share/autogen/opthead.tpl near line 435 */ +/* extracted from /usr/local/share/autogen/opthead.tlib near line 435 */ /* * * * * * * diff --git a/sntp/sntp-opts.texi b/sntp/sntp-opts.texi index 3eaf724a1..30fe1ef4d 100644 --- a/sntp/sntp-opts.texi +++ b/sntp/sntp-opts.texi @@ -1,12 +1,12 @@ @node sntp Invocation @section Invoking sntp @pindex sntp -@cindex standard SNTP program +@cindex standard Simple Network Time Protocol program @ignore # # EDIT THIS FILE WITH CAUTION (sntp-opts.texi) # -# It has been AutoGen-ed January 20, 2011 at 11:16:11 AM by AutoGen 5.11.6pre7 +# It has been AutoGen-ed February 7, 2011 at 02:10:44 AM by AutoGen 5.11.6pre20 # From the definitions sntp-opts.def # and the template file aginfo.tpl @end ignore @@ -47,18 +47,25 @@ This software is released under a specialized copyright license. @menu * sntp usage:: sntp usage help (-?) -* sntp adjtime:: adjtime option (-j) * sntp authentication:: authentication option (-a) +* sntp bctimeout:: bctimeout option (-B) * sntp broadcast:: broadcast option (-b) +* sntp concurrent:: concurrent option (-c) +* sntp debug-level:: debug-level option (-d) * sntp filelog:: filelog option (-l) +* sntp headspace:: headspace option (-h) * sntp ipv4:: ipv4 option (-4) * sntp ipv6:: ipv6 option (-6) * sntp keyfile:: keyfile option (-k) * sntp kod:: kod option (-K) -* sntp normalverbose:: normalverbose option (-d) -* sntp settod:: settod option (-s) -* sntp syslog:: syslog option (-p) -* sntp timeout:: timeout option (-t) +* sntp ntpversion:: ntpversion option (-o) +* sntp set-debug-level:: set-debug-level option (-D) +* sntp slew:: slew option (-s) +* sntp step:: step option (-S) +* sntp steplimit:: steplimit option (-M) +* sntp uctimeout:: uctimeout option (-u) +* sntp usereservedport:: usereservedport option (-r) +* sntp wait:: wait option @end menu @node sntp usage @@ -69,33 +76,42 @@ This is the automatically generated usage text for sntp: @exampleindent 0 @example -sntp - standard SNTP program - Ver. 4.2.7p120 -USAGE: sntp [ - [] | --[@{=| @}] ]... hostname-or-IP ... + 7 Feb 02:10:44 sntp[16648]: sntp 4.2.7p120@@1.2505-o Mon Feb 7 07:10:42 UTC 2011 (16) +sntp - standard Simple Network Time Protocol program - Ver. 4.2.7p120 +USAGE: sntp [ - [] | --[@{=| @}] ]... \ + [ hostname-or-IP ...] Flg Arg Option-Name Description + -d no debug-level Increase output debug message level + - may appear multiple times + -D Str set-debug-level Set the output debug message level + - may appear multiple times -4 no ipv4 Force IPv4 DNS name resolution - prohibits these options: ipv6 -6 no ipv6 Force IPv6 DNS name resolution - prohibits these options: ipv4 - -d no normalverbose Normal verbose - -K Str kod KoD history filename - -p no syslog Logging with syslog - - prohibits these options: - filelog - -l Str filelog Log to specified logfile - - prohibits these options: - syslog - -s no settod Set (step) the time with settimeofday() - - prohibits these options: - adjtime - -j no adjtime Set (slew) the time with adjtime() - - prohibits these options: - settod - -b Str broadcast Use broadcasts to the address specified for synchronisation - -t Num timeout Specify the number of seconds to wait for broadcasts -a Num authentication Enable authentication with the key auth-keynumber - -k Str keyfile Specify a keyfile. SNTP will look in this file for the key specified with -a + -B Num bctimeout The number of seconds to wait for broadcasts + -b Str broadcast Listen to the address specified for broadcast time sync + - may appear multiple times + -c Str concurrent Concurrent query all IPs returned for host-name + - may appear multiple times + -h Num headspace The gap (in milliseconds) between time requests + -K Fil kod KoD history filename + -k Fil keyfile Look in this file for the key specified with -a + -l Fil filelog Log to specified logfile + -M Num steplimit Adjustments less than steplimit msec will be slewed. + - it must be: greater than or equal to 0 + -o Num ntpversion Send as our NTP version + - it must be: 0 to 7 + -r no usereservedport Use the NTP Reserved Port (port 123) + -S no step OK to 'step' the time with settimeofday() + -s no slew OK to 'slew' the time with adjtime() + -u Num uctimeout The number of seconds to wait for unicast responses + no wait Wait for pending replies (if not setting the time) + - disabled as --no-wait + - enabled by default opt version Output version information and exit -? no help Display extended usage information and exit -! no more-help Extended usage information passed thru pager @@ -114,34 +130,19 @@ The following option preset mechanisms are supported: - reading file ./.ntprc - examining environment variables named SNTP_* -sntp implements the Simple Network Time Protocol, and is used to query -an NTP or SNTP server and either display the time or set the local -system's time (given suitable privilege). +sntp implements the Simple Network Time Protocol and is used to query an +NTP or SNTP server and either display the time or set the local system's +time (given suitable privilege). It can be run interactively from the command line or as a cron job. -NTP and SNTP are defined by RFC 5905, which obsoletes RFC 4330 and RFC -1305. +NTP and SNTP are defined by RFC 5905, which obsoletes RFC 4330 and +RFC 1305. please send bug reports to: http://bugs.ntp.org, bugs@@ntp.org @end example @exampleindent 4 -@node sntp adjtime -@subsection adjtime option (-j) -@cindex sntp-adjtime - -This is the ``set (slew) the time with adjtime()'' option. - -This option has some usage constraints. It: -@itemize @bullet -@item -must not appear in combination with any of the following options: -settod. -@end itemize - - - @node sntp authentication @subsection authentication option (-a) @cindex sntp-authentication @@ -151,31 +152,85 @@ This option enables authentication using the key specified in this option's argu The argument of this option is the keyid, a number specified in the keyfile as this key's identifier. See the keyfile option (-k) for more details. +@node sntp bctimeout +@subsection bctimeout option (-B) +@cindex sntp-bctimeout + +This is the ``the number of seconds to wait for broadcasts'' option. +When waiting for a broadcast packet SNTP will wait the number +of seconds specified before giving up. Default 68 seconds. + @node sntp broadcast @subsection broadcast option (-b) @cindex sntp-broadcast -This is the ``use broadcasts to the address specified for synchronisation'' option. -If specified SNTP will listen to the specified broadcast address +This is the ``listen to the address specified for broadcast time sync'' option. + +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +If specified SNTP will listen to the specified address for NTP broadcasts. The default maximum wait time, -68 seconds, can be modified with -t. +68 seconds, can be modified with -B. -@node sntp filelog -@subsection filelog option (-l) -@cindex sntp-filelog +@node sntp concurrent +@subsection concurrent option (-c) +@cindex sntp-concurrent -This is the ``log to specified logfile'' option. +This is the ``concurrent query all ips returned for host-name'' option. This option has some usage constraints. It: @itemize @bullet @item -must not appear in combination with any of the following options: -syslog. +may appear an unlimited number of times. @end itemize +Requests from an NTP "client" to a "server" should never be sent +more rapidly than one every 2 seconds. By default, any IPs returned +as part of a DNS lookup are assumed to be for a single instance of +ntpd, and therefore sntp will send queries to these IPs one after +another, with a 2-second gap in between each query. + +The -c or --concurrent flag says that any IPs returned for the +DNS lookup of the supplied host-name are on different machines, +so we can send concurrent queries. + +@node sntp debug-level +@subsection debug-level option (-d) +@cindex sntp-debug-level + +This is the ``increase output debug message level'' option. + +This option has some usage constraints. It: +@itemize @bullet +@item +may appear an unlimited number of times. +@end itemize + +Increase the debugging message output level. + +@node sntp filelog +@subsection filelog option (-l) +@cindex sntp-filelog + +This is the ``log to specified logfile'' option. This option causes the client to write log messages to the specified logfile. +@node sntp headspace +@subsection headspace option (-h) +@cindex sntp-headspace + +This is the ``the gap (in milliseconds) between time requests'' option. +Since we're only going to use the first valid response we get and +there is benefit to specifying a good number of servers to query, +separate the queries we send out by the specified number of +milliseconds. +Default 10 milliseconds. + @node sntp ipv4 @subsection ipv4 option (-4) @cindex sntp-ipv4 @@ -212,7 +267,7 @@ to the IPv6 namespace. @subsection keyfile option (-k) @cindex sntp-keyfile -This is the ``specify a keyfile. sntp will look in this file for the key specified with -a'' option. +This is the ``look in this file for the key specified with -a'' option. This option specifies the keyfile. SNTP will search for the key specified with -a keyno in this file. Key files follow the following format: @@ -232,54 +287,79 @@ For more information see ntp.keys(5). @cindex sntp-kod This is the ``kod history filename'' option. -Modifies the filename to be used to persist the history of KoD +Specifies the filename to be used for the persistent history of KoD responses received from servers. The default is /var/db/ntp-kod. -@node sntp normalverbose -@subsection normalverbose option (-d) -@cindex sntp-normalverbose +@node sntp ntpversion +@subsection ntpversion option (-o) +@cindex sntp-ntpversion -This is the ``normal verbose'' option. -Diagnostic messages for non-fatal errors and a limited amount of -tracing should be written to standard error. Fatal ones always -produce a diagnostic. This option should be set when there is a -suspected problem with the server, network or the source. +This is the ``send as our ntp version'' option. +When sending requests to a remote server, tell them we are running +NTP protocol version . -@node sntp settod -@subsection settod option (-s) -@cindex sntp-settod +@node sntp set-debug-level +@subsection set-debug-level option (-D) +@cindex sntp-set-debug-level -This is the ``set (step) the time with settimeofday()'' option. +This is the ``set the output debug message level'' option. This option has some usage constraints. It: @itemize @bullet @item -must not appear in combination with any of the following options: -adjtime. +may appear an unlimited number of times. @end itemize +Set the output debugging level. Can be supplied multiple times, +but each overrides the previous value(s). +@node sntp slew +@subsection slew option (-s) +@cindex sntp-slew -@node sntp syslog -@subsection syslog option (-p) -@cindex sntp-syslog +This is the ``ok to 'slew' the time with adjtime()'' option. -This is the ``logging with syslog'' option. + +@node sntp step +@subsection step option (-S) +@cindex sntp-step + +This is the ``ok to 'step' the time with settimeofday()'' option. + + +@node sntp steplimit +@subsection steplimit option (-M) +@cindex sntp-steplimit + +This is the ``adjustments less than steplimit msec will be slewed.'' option. +If the time adjustment is less than steplimit milliseconds, slew the amount using adjtime(). Otherwise, step the correction using settimeofday(). + +@node sntp uctimeout +@subsection uctimeout option (-u) +@cindex sntp-uctimeout + +This is the ``the number of seconds to wait for unicast responses'' option. +When waiting for a unicast reply, SNTP will wait the number +of seconds specified before giving up. Default 5 seconds. + +@node sntp usereservedport +@subsection usereservedport option (-r) +@cindex sntp-usereservedport + +This is the ``use the ntp reserved port (port 123)'' option. +Use port 123, which is reserved for NTP, for our network communications. + +@node sntp wait +@subsection wait option +@cindex sntp-wait + +This is the ``wait for pending replies (if not setting the time)'' option. This option has some usage constraints. It: @itemize @bullet @item -must not appear in combination with any of the following options: -filelog. +is enabled by default. @end itemize -When this option is set all logging will be done using syslog. - -@node sntp timeout -@subsection timeout option (-t) -@cindex sntp-timeout - -This is the ``specify the number of seconds to wait for broadcasts'' option. -When waiting for a broadcast packet SNTP will wait the number -of seconds specified before giving up. Default 68 seconds. +If we are not setting the time, wait for all pending responses. diff --git a/sntp/sntp.1 b/sntp/sntp.1 index f4880c315..5772d84fa 100644 --- a/sntp/sntp.1 +++ b/sntp/sntp.1 @@ -1,19 +1,19 @@ -.TH SNTP 1 2011-01-20 "( 4.2.7p120)" "Programmer's Manual" +.TH SNTP 1 2011-02-07 "( 4.2.7p120)" "Programmer's Manual" .\" EDIT THIS FILE WITH CAUTION (sntp.1) .\" -.\" It has been AutoGen-ed January 20, 2011 at 11:16:10 AM by AutoGen 5.11.6pre7 +.\" It has been AutoGen-ed February 7, 2011 at 02:10:44 AM by AutoGen 5.11.6pre20 .\" From the definitions sntp-opts.def .\" and the template file agman1.tpl .\" .SH NAME -sntp \- standard SNTP program +sntp \- standard Simple Network Time Protocol program .SH SYNOPSIS .B sntp .\" Mixture of short (flag) options and long options .RB [ \-\fIflag\fP " [\fIvalue\fP]]... [" \--\fIopt-name\fP " [[=| ]\fIvalue\fP]]..." .br .in +8 -hostname-or-IP ... +[ hostname-or-IP ...] .PP .SH "DESCRIPTION" @@ -47,6 +47,19 @@ is believed to be correct to within seconds. .SH OPTIONS .TP +.BR \-d ", " \--debug-level +Increase output debug message level. +This option may appear an unlimited number of times. +.sp +Increase the debugging message output level. +.TP +.BR \-D " \fIstring\fP, " \--set-debug-level "=" \fIstring\fP +Set the output debug message level. +This option may appear an unlimited number of times. +.sp +Set the output debugging level. Can be supplied multiple times, +but each overrides the previous value(s). +.TP .BR \-4 ", " \--ipv4 Force IPv4 DNS name resolution. This option must not appear in combination with any of the following options: @@ -63,77 +76,71 @@ ipv4. Force DNS resolution of following host names on the command line to the IPv6 namespace. .TP -.BR \-d ", " \--normalverbose -Normal verbose. -.sp -Diagnostic messages for non-fatal errors and a limited amount of -tracing should be written to standard error. Fatal ones always -produce a diagnostic. This option should be set when there is a -suspected problem with the server, network or the source. -.TP -.BR \-K " \fIfile-name\fP, " \--kod "=" \fIfile-name\fP -KoD history filename. -.sp -Modifies the filename to be used to persist the history of KoD -responses received from servers. The default is -/var/db/ntp-kod. -.TP -.BR \-p ", " \--syslog -Logging with syslog. -This option must not appear in combination with any of the following options: -filelog. +.BR \-a " \fIauth-keynumber\fP, " \--authentication "=" \fIauth-keynumber\fP +Enable authentication with the key auth-keynumber. +This option takes an integer number as its argument. .sp -When this option is set all logging will be done using syslog. +This option enables authentication using the key specified in this option's argument. +The argument of this option is the keyid, a number specified in the keyfile as this +key's identifier. See the keyfile option (-k) for more details. .TP -.BR \-l " \fIfile-name\fP, " \--filelog "=" \fIfile-name\fP -Log to specified logfile. -This option must not appear in combination with any of the following options: -syslog. +.BR \-B " \fIseconds\fP, " \--bctimeout "=" \fIseconds\fP +The number of seconds to wait for broadcasts. +This option takes an integer number as its argument. +The default \fIseconds\fP for this option is: +.ti +4 + 68 .sp -This option causes the client to write log messages to the specified -logfile. +When waiting for a broadcast packet SNTP will wait the number +of seconds specified before giving up. Default 68 seconds. .TP -.BR \-s ", " \--settod -Set (step) the time with settimeofday(). -This option must not appear in combination with any of the following options: -adjtime. +.BR \-b " \fIbroadcast-address\fP, " \--broadcast "=" \fIbroadcast-address\fP +Listen to the address specified for broadcast time sync. +This option may appear an unlimited number of times. .sp - +If specified SNTP will listen to the specified address +for NTP broadcasts. The default maximum wait time, +68 seconds, can be modified with \-B. .TP -.BR \-j ", " \--adjtime -Set (slew) the time with adjtime(). -This option must not appear in combination with any of the following options: -settod. +.BR \-c " \fIhost-name\fP, " \--concurrent "=" \fIhost-name\fP +Concurrent query all IPs returned for host-name. +This option may appear an unlimited number of times. .sp +Requests from an NTP "client" to a "server" should never be sent +more rapidly than one every 2 seconds. By default, any IPs returned +as part of a DNS lookup are assumed to be for a single instance of +ntpd, and therefore sntp will send queries to these IPs one after +another, with a 2-second gap in between each query. +The \-c or \--concurrent flag says that any IPs returned for the +DNS lookup of the supplied host-name are on different machines, +so we can send concurrent queries. .TP -.BR \-b " \fIbroadcast-address\fP, " \--broadcast "=" \fIbroadcast-address\fP -Use broadcasts to the address specified for synchronisation. -.sp -If specified SNTP will listen to the specified broadcast address -for NTP broadcasts. The default maximum wait time, -68 seconds, can be modified with \-t. -.TP -.BR \-t " \fIseconds\fP, " \--timeout "=" \fIseconds\fP -Specify the number of seconds to wait for broadcasts. +.BR \-h " \fImilliseconds\fP, " \--headspace "=" \fImilliseconds\fP +The gap (in milliseconds) between time requests. This option takes an integer number as its argument. -The default \fIseconds\fP for this option is: +The default \fImilliseconds\fP for this option is: .ti +4 - 68 + 10 .sp -When waiting for a broadcast packet SNTP will wait the number -of seconds specified before giving up. Default 68 seconds. +Since we're only going to use the first valid response we get and +there is benefit to specifying a good number of servers to query, +separate the queries we send out by the specified number of +milliseconds. +Default 10 milliseconds. .TP -.BR \-a " \fIauth-keynumber\fP, " \--authentication "=" \fIauth-keynumber\fP -Enable authentication with the key auth-keynumber. -This option takes an integer number as its argument. +.BR \-K " \fIfile-name\fP, " \--kod "=" \fIfile-name\fP +KoD history filename. +The default \fIfile-name\fP for this option is: +.ti +4 + /var/db/ntp-kod .sp -This option enables authentication using the key specified in this option's argument. -The argument of this option is the keyid, a number specified in the keyfile as this -key's identifier. See the keyfile option (-k) for more details. +Specifies the filename to be used for the persistent history of KoD +responses received from servers. The default is +/var/db/ntp-kod. .TP .BR \-k " \fIfile-name\fP, " \--keyfile "=" \fIfile-name\fP -Specify a keyfile. SNTP will look in this file for the key specified with \-a. +Look in this file for the key specified with \-a. .sp This option specifies the keyfile. SNTP will search for the key specified with \-a keyno in this file. Key files follow the following format: @@ -149,6 +156,74 @@ M Key in a 1-to-8 character ASCII string using the MD5 authentication scheme. For more information see ntp.keys(5). .TP +.BR \-l " \fIfile-name\fP, " \--filelog "=" \fIfile-name\fP +Log to specified logfile. +.sp +This option causes the client to write log messages to the specified +logfile. +.TP +.BR \-M " \fInumber\fP, " \--steplimit "=" \fInumber\fP +Adjustments less than steplimit msec will be slewed.. +This option takes an integer number as its argument. +The value of \fInumber\fP is constrained to being: +.in +4 +.nf +.na +greater than or equal to 0 +.fi +.in -4 +.sp +If the time adjustment is less than steplimit milliseconds, slew the amount using adjtime(). Otherwise, step the correction using settimeofday(). +.TP +.BR \-o " \fInumber\fP, " \--ntpversion "=" \fInumber\fP +Send as our NTP version. +This option takes an integer number as its argument. +The value of \fInumber\fP is constrained to being: +.in +4 +.nf +.na +in the range 0 through 7 +.fi +.in -4 +The default \fInumber\fP for this option is: +.ti +4 + 4 +.sp +When sending requests to a remote server, tell them we are running +NTP protocol version . +.TP +.BR \-r ", " \--usereservedport +Use the NTP Reserved Port (port 123). +.sp +Use port 123, which is reserved for NTP, for our network communications. +.TP +.BR \-S ", " \--step +OK to 'step' the time with settimeofday(). +.sp + +.TP +.BR \-s ", " \--slew +OK to 'slew' the time with adjtime(). +.sp + +.TP +.BR \-u " \fIseconds\fP, " \--uctimeout "=" \fIseconds\fP +The number of seconds to wait for unicast responses. +This option takes an integer number as its argument. +The default \fIseconds\fP for this option is: +.ti +4 + 5 +.sp +When waiting for a unicast reply, SNTP will wait the number +of seconds specified before giving up. Default 5 seconds. +.TP +.BR \--wait, " \fB--no-wait\fP" +Wait for pending replies (if not setting the time). +The \fIno-wait\fP form will disable the option. +This option is enabled by default. +.sp +If we are not setting the time, wait for all pending responses. +.TP .BR \-? , " \--help" Display extended usage information and exit. .TP diff --git a/sntp/sntp.html b/sntp/sntp.html index 0094e7610..93b720d4b 100644 --- a/sntp/sntp.html +++ b/sntp/sntp.html @@ -3,7 +3,7 @@ Sntp User's Manual - + @@ -38,7 +38,7 @@ display the time offset of the system clock relative to the server clock. Run as root, it can correct the system clock to this offset as well. It can be run as an interactive command or from a cron job. -

This document applies to version 4.2.7p114 of sntp. +

This document applies to version {No value for `VERSION'} of sntp.

The program implements the SNTP protocol as defined by RFC 5905, the NTPv4 IETF specification. @@ -87,7 +87,7 @@ error bound of the system clock relative to the server clock.

Invoking sntp

-

+

sntp can be used as a SNTP client to query a NTP or SNTP server and either display the time or set the local system's time (given suitable privilege). It can be @@ -127,8 +127,9 @@ the aginfo template and the option descriptions for the sntp concurrent: concurrent option (-c)

  • sntp debug-level: debug-level option (-d)
  • sntp filelog: filelog option (-l) -
  • sntp ipv4: ipv4 option (-4) -
  • sntp ipv6: ipv6 option (-6) +
  • sntp headspace: headspace option (-h) +
  • sntp ipv4: ipv4 option (-4) +
  • sntp ipv6: ipv6 option (-6)
  • sntp keyfile: keyfile option (-k)
  • sntp kod: kod option (-K)
  • sntp ntpversion: ntpversion option (-o) @@ -136,7 +137,9 @@ the aginfo template and the option descriptions for the sntp slew: slew option (-s)
  • sntp step: step option (-S)
  • sntp steplimit: steplimit option (-M) +
  • sntp uctimeout: uctimeout option (-u)
  • sntp usereservedport: usereservedport option (-r) +
  • sntp wait: wait option
    @@ -152,7 +155,8 @@ Up: sntp Invocation

    This is the automatically generated usage text for sntp: -

    sntp - standard SNTP program - Ver. 4.2.7p120
    +
     7 Feb 02:10:44 sntp[16648]: sntp 4.2.7p120@1.2505-o Mon Feb  7 07:10:42 UTC 2011 (16)
    +sntp - standard Simple Network Time Protocol program - Ver. 4.2.7p120
     USAGE:  sntp [ -<flag> [<val>] | --<name>[{=| }<val>] ]... \
                     [ hostname-or-IP ...]
       Flg Arg Option-Name    Description
    @@ -167,14 +171,15 @@ USAGE:  sntp [ -<flag> [<val>] | --<name>[{=| }<val>] ].
                                     - prohibits these options:
                                     ipv4
        -a Num authentication Enable authentication with the key auth-keynumber
    -   -B Num bctimeout      Specify the number of seconds to wait for broadcasts
    +   -B Num bctimeout      The number of seconds to wait for broadcasts
        -b Str broadcast      Listen to the address specified for broadcast time sync
                                     - may appear multiple times
        -c Str concurrent     Concurrent query all IPs returned for host-name
                                     - may appear multiple times
    -   -l Fil filelog        Log to specified logfile
    +   -h Num headspace      The gap (in milliseconds) between time requests
        -K Fil kod            KoD history filename
    -   -k Fil keyfile        Specify a keyfile. SNTP will look in this file for the key specified with -a
    +   -k Fil keyfile        Look in this file for the key specified with -a
    +   -l Fil filelog        Log to specified logfile
        -M Num steplimit      Adjustments less than steplimit msec will be slewed.
                                     - it must be:  greater than or equal to 0
        -o Num ntpversion     Send <int> as our NTP version
    @@ -182,6 +187,10 @@ USAGE:  sntp [ -<flag> [<val>] | --<name>[{=| }<val>] ].
        -r no  usereservedport Use the NTP Reserved Port (port 123)
        -S no  step           OK to 'step' the time with settimeofday()
        -s no  slew           OK to 'slew' the time with adjtime()
    +   -u Num uctimeout      The number of seconds to wait for unicast responses
    +      no  wait           Wait for pending replies (if not setting the time)
    +                                - disabled as --no-wait
    +                                - enabled by default
           opt version        Output version information and exit
        -? no  help           Display extended usage information and exit
        -! no  more-help      Extended usage information passed thru pager
    @@ -200,14 +209,14 @@ The following option preset mechanisms are supported:
      - reading file ./.ntprc
      - examining environment variables named SNTP_*
     
    -sntp implements the Simple Network Time Protocol and is used to query
    -an NTP or SNTP server and either display the time or set the local
    -system's time (given suitable privilege).
    +sntp implements the Simple Network Time Protocol and is used to query an
    +NTP or SNTP server and either display the time or set the local system's
    +time (given suitable privilege).
     
     It can be run interactively from the command line or as a cron job.
     
    -NTP and SNTP are defined by RFC 5905, which obsoletes RFC 4330 and RFC
    -1305.
    +NTP and SNTP are defined by RFC 5905, which obsoletes RFC 4330 and
    +RFC 1305.
     
     please send bug reports to:  http://bugs.ntp.org, bugs@ntp.org
     
    @@ -240,7 +249,7 @@ Up: sntp Invocation

    bctimeout option (-B)

    -This is the “specify the number of seconds to wait for broadcasts” option. +This is the “the number of seconds to wait for broadcasts” option. When waiting for a broadcast packet SNTP will wait the number of seconds specified before giving up. Default 68 seconds. @@ -321,7 +330,7 @@ This is the “increase output debug message level” option.


    -Next: , +Next: , Previous: sntp debug-level, Up: sntp Invocation @@ -334,18 +343,37 @@ This is the “log to specified logfile” option. This option causes the client to write log messages to the specified logfile. +
    +


    + +Next: , +Previous: sntp filelog, +Up: sntp Invocation + +
    + +

    headspace option (-h)

    + +

    +This is the “the gap (in milliseconds) between time requests” option. +Since we're only going to use the first valid response we get and +there is benefit to specifying a good number of servers to query, +separate the queries we send out by the specified number of +milliseconds. +Default 10 milliseconds. +


    Next: , -Previous: sntp filelog, +Previous: sntp headspace, Up: sntp Invocation

    ipv4 option (-4)

    -

    +

    This is the “force ipv4 dns name resolution” option.

    This option has some usage constraints. It: @@ -368,7 +396,7 @@ Up: sntp Invocation

    ipv6 option (-6)

    -

    +

    This is the “force ipv6 dns name resolution” option.

    This option has some usage constraints. It: @@ -391,8 +419,8 @@ Up: sntp Invocation

    keyfile option (-k)

    -

    -This is the “specify a keyfile. sntp will look in this file for the key specified with -a” option. +

    +This is the “look in this file for the key specified with -a” option. This option specifies the keyfile. SNTP will search for the key specified with -a keyno in this file. Key files follow the following format: @@ -418,7 +446,7 @@ Up: sntp Invocation

    kod option (-K)

    -

    +

    This is the “kod history filename” option. Specifies the filename to be used for the persistent history of KoD responses received from servers. The default is @@ -435,7 +463,7 @@ Up: sntp Invocation

    ntpversion option (-o)

    -

    +

    This is the “send <int> as our ntp version” option. When sending requests to a remote server, tell them we are running NTP protocol version <ntpversion> . @@ -452,7 +480,7 @@ Up: sntp Invocation

    set-debug-level option (-D)

    -

    +

    This is the “set the output debug message level” option.

    This option has some usage constraints. It: @@ -474,7 +502,7 @@ Up: sntp Invocation

    slew option (-s)

    -

    +

    This is the “ok to 'slew' the time with adjtime()” option.

    @@ -488,13 +516,13 @@ Up: sntp Invocation

    step option (-S)

    -

    +

    This is the “ok to 'step' the time with settimeofday()” option.


    -Next: , +Next: , Previous: sntp step, Up: sntp Invocation @@ -502,24 +530,61 @@ Up: sntp Invocation

    steplimit option (-M)

    -

    +

    This is the “adjustments less than steplimit msec will be slewed.” option. If the time adjustment is less than steplimit milliseconds, slew the amount using adjtime(). Otherwise, step the correction using settimeofday().


    - + +Next: , Previous: sntp steplimit, Up: sntp Invocation
    +

    uctimeout option (-u)

    + +

    +This is the “the number of seconds to wait for unicast responses” option. +When waiting for a unicast reply, SNTP will wait the number +of seconds specified before giving up. Default 5 seconds. + +

    +


    + +Next: , +Previous: sntp uctimeout, +Up: sntp Invocation + +
    +

    usereservedport option (-r)

    -

    +

    This is the “use the ntp reserved port (port 123)” option. Use port 123, which is reserved for NTP, for our network communications. +

    +


    + +Previous: sntp usereservedport, +Up: sntp Invocation + +
    + +

    wait option

    + +

    +This is the “wait for pending replies (if not setting the time)” option. + +

    This option has some usage constraints. It: +

      +
    • is enabled by default. +
    + +

    If we are not setting the time, wait for all pending responses. +


    diff --git a/sntp/tests/Makefile.am b/sntp/tests/Makefile.am index 96147d647..6b852d70f 100644 --- a/sntp/tests/Makefile.am +++ b/sntp/tests/Makefile.am @@ -7,63 +7,72 @@ endif sntp_objs = .. -sntp_SOURCES_USED = $(sntp_objs)/crypto.o \ - $(sntp_objs)/kod_management.o \ - $(sntp_objs)/log.o \ - $(sntp_objs)/main.o \ - $(sntp_objs)/networking.o \ - $(sntp_objs)/sntp-opts.o \ - $(sntp_objs)/utilities.o \ - $(NULL) - -base_SOURCES = $(srcdir)/../tests_main.cpp \ - sntptest.cpp \ - $(NULL) - -tests_SOURCES = $(base_SOURCES) \ - crypto.cpp \ - keyFile.cpp \ - kodDatabase.cpp \ - kodFile.cpp \ - networking.cpp \ - packetHandling.cpp \ - packetProcessing.cpp \ - utilities.cpp \ - $(NULL) - -noinst_HEADERS = sntptest.h \ - fileHandlingTest.h \ - $(NULL) +sntp_SOURCES_USED = \ + $(sntp_objs)/crypto.o \ + $(sntp_objs)/kod_management.o \ + $(sntp_objs)/log.o \ + $(sntp_objs)/main.o \ + $(sntp_objs)/networking.o \ + $(sntp_objs)/sntp-opts.o \ + $(sntp_objs)/utilities.o \ + $(sntp_objs)/version.o \ + $(NULL) + +base_SOURCES = \ + $(srcdir)/../tests_main.cpp \ + sntptest.cpp \ + $(NULL) + +tests_SOURCES = \ + $(base_SOURCES) \ + crypto.cpp \ + keyFile.cpp \ + kodDatabase.cpp \ + kodFile.cpp \ + networking.cpp \ + packetHandling.cpp \ + packetProcessing.cpp \ + utilities.cpp \ + $(NULL) + +noinst_HEADERS = \ + sntptest.h \ + fileHandlingTest.h \ + $(NULL) dist_check_SCRIPTS = test-driver EXTRA_DIST = data -CLEANFILES = data/kod-output-multiple \ - data/kod-output-single \ - data/debug-output-pkt \ - data/debug-output-lfp-dec \ - data/kod-output-blank \ - data/debug-output-lfp-bin \ - data/debug-output-lfp-hex \ - $(NULL) - -LDADD = $(LIBOPTS_LDADD) \ - @top_builddir@/../libntp/libntp.a \ - @LCRYPTO@ \ - @GTEST_LDFLAGS@ \ - @GTEST_LIBS@ \ - $(sntp_SOURCES_USED) \ - $(NULL) +CLEANFILES = \ + data/kod-output-multiple \ + data/kod-output-single \ + data/debug-output-pkt \ + data/debug-output-lfp-dec \ + data/kod-output-blank \ + data/debug-output-lfp-bin \ + data/debug-output-lfp-hex \ + $(NULL) + +LDADD = \ + $(LIBOPTS_LDADD) \ + @LDADD_LIBEVENT@ \ + @top_builddir@/../libntp/libntp.a \ + @LDADD_LIBNTP@ \ + @LCRYPTO@ \ + @GTEST_LDFLAGS@ \ + @GTEST_LIBS@ \ + $(sntp_SOURCES_USED) \ + $(NULL) AM_CFLAGS = @CFLAGS_NTP@ AM_CXXFLAGS = @GTEST_CXXFLAGS@ -AM_CPPFLAGS = @GTEST_CPPFLAGS@ @CPPFLAGS_NTP@ +AM_CPPFLAGS = @CPPFLAGS_LIBEVENT@ @GTEST_CPPFLAGS@ @CPPFLAGS_NTP@ INCLUDES = $(LIBOPTS_CFLAGS) INCLUDES += -I$(top_srcdir)/../include INCLUDES += -I$(top_srcdir)/../lib/isc/include -INCLUDES += -I$(top_srcdir)/../lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/../lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/../lib/isc/unix/include INCLUDES += -I$(top_srcdir)/../tests INCLUDES += -I$(top_srcdir) diff --git a/sntp/tests/kodDatabase.cpp b/sntp/tests/kodDatabase.cpp index d92234fac..515f4337a 100644 --- a/sntp/tests/kodDatabase.cpp +++ b/sntp/tests/kodDatabase.cpp @@ -7,7 +7,7 @@ extern "C" { class kodDatabaseTest : public sntptest { protected: virtual void SetUp() { - kod_init_kod_db("/dev/null"); + kod_init_kod_db("/dev/null", TRUE); } }; diff --git a/sntp/tests/kodFile.cpp b/sntp/tests/kodFile.cpp index aed65ee4e..e1775f637 100644 --- a/sntp/tests/kodFile.cpp +++ b/sntp/tests/kodFile.cpp @@ -22,25 +22,17 @@ protected: } virtual void TearDown() { - /* - * When calling kod_init_kod_db(), it will place an exit handler - * that runs write_kod_db() when the test executable stops running. - * To prevent write_kod_db() from messing up our pre-written input - * files, kod_db_file is set to /dev/null at the end of every test. - */ - - kod_db_file = estrdup("/dev/null"); } }; TEST_F(kodFileTest, ReadEmptyFile) { - kod_init_kod_db(CreatePath("kod-test-empty", INPUT_DIR).c_str()); + kod_init_kod_db(CreatePath("kod-test-empty", INPUT_DIR).c_str(), TRUE); EXPECT_EQ(0, kod_db_cnt); } TEST_F(kodFileTest, ReadCorrectFile) { - kod_init_kod_db(CreatePath("kod-test-correct", INPUT_DIR).c_str()); + kod_init_kod_db(CreatePath("kod-test-correct", INPUT_DIR).c_str(), TRUE); EXPECT_EQ(2, kod_db_cnt); @@ -58,7 +50,7 @@ TEST_F(kodFileTest, ReadCorrectFile) { } TEST_F(kodFileTest, ReadFileWithBlankLines) { - kod_init_kod_db(CreatePath("kod-test-blanks", INPUT_DIR).c_str()); + kod_init_kod_db(CreatePath("kod-test-blanks", INPUT_DIR).c_str(), TRUE); EXPECT_EQ(3, kod_db_cnt); diff --git a/sntp/tests/nameresolution.cpp b/sntp/tests/nameresolution.cpp new file mode 100644 index 000000000..d7d6193bf --- /dev/null +++ b/sntp/tests/nameresolution.cpp @@ -0,0 +1,171 @@ +#include "sntptest.h" + +extern "C" { +#include "networking.h" +}; + +class networkingTest : public sntptest { +protected: + ::testing::AssertionResult CompareAddrinfo(const char* host, + int family, int flags, + const addrinfo& actual) { + if (family != actual.ai_family) + return ::testing::AssertionFailure() + << "Family mismatch, expected: " << family + << " but was: " << actual.ai_family; + sockaddr_u* sock = new sockaddr_u; + void* expectedaddr = NULL, *actualaddr = NULL; + int size = 0, addrsize = 0; + if (family == AF_INET) { + expectedaddr = &sock->sa4.sin_addr; + actualaddr = &((sockaddr_u*)actual.ai_addr)->sa4.sin_addr; + size = sizeof(sock->sa4); + addrsize = sizeof(sock->sa4.sin_addr); + } else { + expectedaddr = &sock->sa6.sin6_addr; + actualaddr = &((sockaddr_u*)actual.ai_addr)->sa6.sin6_addr; + size = sizeof(sock->sa6); + addrsize = sizeof(sock->sa6.sin6_addr); + } + sock->sa.sa_family = family; + + if (inet_pton(family, host, expectedaddr) != 1) + return ::testing::AssertionFailure() + << "inet_pton failed!"; + + if (flags != actual.ai_flags) + return ::testing::AssertionFailure() + << "Flags mismatch, expected: " << flags + << " but was: " << actual.ai_flags; + + if (size != actual.ai_addrlen) + return ::testing::AssertionFailure() + << "Address length mismatch, expected: " << size + << " but was: " << actual.ai_addrlen; + + if (memcmp(expectedaddr, actualaddr, addrsize) != 0) + return ::testing::AssertionFailure() + << "Address mismatch"; + return ::testing::AssertionSuccess(); + } +}; + +TEST_F(networkingTest, ResolveSingleAddress) { + const char* HOSTS[1] = {"192.0.2.1"}; + const int HOSTCOUNT = COUNTOF(HOSTS); + + addrinfo** actual = NULL; + + ASSERT_EQ(1, resolve_hosts(HOSTS, HOSTCOUNT, &actual, PF_UNSPEC)); + + ASSERT_TRUE(actual != NULL); + EXPECT_TRUE(CompareAddrinfo(HOSTS[0], AF_INET, 0, **actual)); +} + +TEST_F(networkingTest, ResolveMultipleAddresses) { + const char* HOSTS[3] = {"192.0.2.1", "192.0.2.5", "192.0.2.10"}; + const int HOSTCOUNT = COUNTOF(HOSTS); + + addrinfo** actual = NULL; + + ASSERT_EQ(3, resolve_hosts(HOSTS, HOSTCOUNT, &actual, PF_UNSPEC)); + + ASSERT_TRUE(actual != NULL); + for (int i=0; isa4.sin_addr; - actualaddr = &((sockaddr_u*)actual.ai_addr)->sa4.sin_addr; - size = sizeof(sock->sa4); - addrsize = sizeof(sock->sa4.sin_addr); - } else { - expectedaddr = &sock->sa6.sin6_addr; - actualaddr = &((sockaddr_u*)actual.ai_addr)->sa6.sin6_addr; - size = sizeof(sock->sa6); - addrsize = sizeof(sock->sa6.sin6_addr); - } - sock->sa.sa_family = family; - - if (inet_pton(family, host, expectedaddr) != 1) - return ::testing::AssertionFailure() - << "inet_pton failed!"; - - if (flags != actual.ai_flags) - return ::testing::AssertionFailure() - << "Flags mismatch, expected: " << flags - << " but was: " << actual.ai_flags; - - if (size != actual.ai_addrlen) - return ::testing::AssertionFailure() - << "Address length mismatch, expected: " << size - << " but was: " << actual.ai_addrlen; - - if (memcmp(expectedaddr, actualaddr, addrsize) != 0) - return ::testing::AssertionFailure() - << "Address mismatch"; - return ::testing::AssertionSuccess(); - } -}; - -TEST_F(networkingTest, ResolveSingleAddress) { - const char* HOSTS[1] = {"192.0.2.1"}; - const int HOSTCOUNT = COUNTOF(HOSTS); - - addrinfo** actual = NULL; - - ASSERT_EQ(1, resolve_hosts(HOSTS, HOSTCOUNT, &actual, PF_UNSPEC)); - - ASSERT_TRUE(actual != NULL); - EXPECT_TRUE(CompareAddrinfo(HOSTS[0], AF_INET, 0, **actual)); -} - -TEST_F(networkingTest, ResolveMultipleAddresses) { - const char* HOSTS[3] = {"192.0.2.1", "192.0.2.5", "192.0.2.10"}; - const int HOSTCOUNT = COUNTOF(HOSTS); - - addrinfo** actual = NULL; - - ASSERT_EQ(3, resolve_hosts(HOSTS, HOSTCOUNT, &actual, PF_UNSPEC)); - - ASSERT_TRUE(actual != NULL); - for (int i=0; itype, 4) == 0); } TEST_F(mainTest, HandleKodRate) { - pkt rpkt; - addrinfo host; - int rpktl = KOD_RATE; - - EXPECT_EQ(1, handle_pkt(rpktl, &rpkt, &host)); + pkt rpkt; + sockaddr_u host; + int rpktl; + + ZERO(rpkt); + ZERO(host); + rpktl = KOD_RATE; + EXPECT_EQ(1, handle_pkt(rpktl, &rpkt, &host, "")); } TEST_F(mainTest, HandleCorrectPacket) { - // We don't want our testing code to actually change the system clock. - ASSERT_FALSE(ENABLED_OPT(SETTOD)); - ASSERT_FALSE(ENABLED_OPT(ADJTIME)); + pkt rpkt; + sockaddr_u host; + int rpktl; + l_fp now; - pkt rpkt; - addrinfo host; - int rpktl = LEN_PKT_NOMAC; + // We don't want our testing code to actually change the system clock. + ASSERT_FALSE(ENABLED_OPT(STEP)); + ASSERT_FALSE(ENABLED_OPT(SLEW)); - l_fp now; get_systime(&now); HTONL_FP(&now, &rpkt.reftime); HTONL_FP(&now, &rpkt.org); HTONL_FP(&now, &rpkt.rec); HTONL_FP(&now, &rpkt.xmt); + rpktl = LEN_PKT_NOMAC; + ZERO(host); + AF(&host) = AF_INET; - EXPECT_EQ(0, handle_pkt(rpktl, &rpkt, &host)); + EXPECT_EQ(0, handle_pkt(rpktl, &rpkt, &host, "")); } +/* packetHandling.cpp */ diff --git a/sntp/utilities.c b/sntp/utilities.c index e19ee1c35..2ce9b8e49 100644 --- a/sntp/utilities.c +++ b/sntp/utilities.c @@ -112,17 +112,18 @@ l_fp_output_dec ( */ char * addrinfo_to_str ( - struct addrinfo *addr + const struct addrinfo *addr ) { sockaddr_u s; - memset(&s, 0, sizeof(s)); + ZERO(s); memcpy(&s, addr->ai_addr, min(sizeof(s), addr->ai_addrlen)); return ss_to_str(&s); } + /* Convert a sockaddr_u to a string containing the address in * style of inet_ntoa * Why not switch callers to use stoa from libntp? No free() needed @@ -140,6 +141,8 @@ ss_to_str ( return buf; } + + /* * Converts a struct tv to a date string */ @@ -185,6 +188,3 @@ tv_to_str( return buf; } - - - diff --git a/sntp/utilities.h b/sntp/utilities.h index a122f868d..c35cf39cd 100644 --- a/sntp/utilities.h +++ b/sntp/utilities.h @@ -18,7 +18,7 @@ void l_fp_output (l_fp *ts, FILE *output); void l_fp_output_bin (l_fp *ts, FILE *output); void l_fp_output_dec (l_fp *ts, FILE *output); -char *addrinfo_to_str (struct addrinfo *addr); +char *addrinfo_to_str (const struct addrinfo *addr); char *ss_to_str (sockaddr_u *saddr); char *tv_to_str (const struct timeval *tv); diff --git a/tests/libntp/Makefile.am b/tests/libntp/Makefile.am index 3439f5757..8e92a630e 100644 --- a/tests/libntp/Makefile.am +++ b/tests/libntp/Makefile.am @@ -4,6 +4,8 @@ check_PROGRAMS = tests LDADD = \ @top_builddir@/libntp/libntp.a \ + @LDADD_LIBNTP@ \ + @PTHREAD_LIBS@ \ @LCRYPTO@ \ @GTEST_LDFLAGS@ \ @GTEST_LIBS@ \ @@ -13,6 +15,12 @@ AM_CFLAGS = @CFLAGS_NTP@ AM_CXXFLAGS = @GTEST_CXXFLAGS@ AM_CPPFLAGS = @GTEST_CPPFLAGS@ @CPPFLAGS_NTP@ +INCLUDES = -I$(top_srcdir)/include +INCLUDES += -I$(top_srcdir)/lib/isc/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include +INCLUDES += -I$(top_srcdir)/lib/isc/unix/include +INCLUDES += -I$(top_srcdir)/sntp + tests_SOURCES = $(top_srcdir)/sntp/tests_main.cpp \ libntptest.cpp \ a_md5encrypt.cpp \ @@ -58,12 +66,6 @@ noinst_HEADERS = lfptest.h \ libntptest.h \ sockaddrtest.h -INCLUDES = -I$(top_srcdir)/include -INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include -INCLUDES += -I$(top_srcdir)/lib/isc/unix/include -INCLUDES += -I$(top_srcdir)/sntp - TESTS = if !NTP_CROSSCOMPILE diff --git a/tests/libntp/clocktime.cpp b/tests/libntp/clocktime.cpp index efda8c5c8..a24df1af4 100644 --- a/tests/libntp/clocktime.cpp +++ b/tests/libntp/clocktime.cpp @@ -154,15 +154,25 @@ TEST_F(clocktimeTest, NoReasonableConversion) { TEST_F(clocktimeTest, AlwaysInLimit) { /* Timestamp is: 2010-01-02 11:00:00Z */ const u_int32 timestamp = 3471418800UL; - - int cyc, yday, hour, minute, second; - u_long yearstart = 0; - u_int32 actual, diff; - + const u_short prime_incs[] = { 127, 151, 163, 179 }; + int cyc; + int yday; + u_char whichprime; + u_short ydayinc; + int hour; + int minute; + int second; + u_long yearstart; + u_int32 actual; + u_int32 diff; + + yearstart = 0; for (cyc = 0; cyc < 5; cyc++) { - settime(1900+cyc*65, 1, 1, 0, 0, 0); - for (yday = -26000; yday < 26000; yday += 17) - for (hour = -204; hour < 204; hour+=2) + settime(1900 + cyc * 65, 1, 1, 0, 0, 0); + for (yday = -26000; yday < 26000; yday += ydayinc) { + whichprime = abs(yday) % COUNTOF(prime_incs); + ydayinc = prime_incs[whichprime]; + for (hour = -204; hour < 204; hour += 2) { for (minute = -60; minute < 60; minute++) { clocktime(yday, hour, minute, 30, 0, timestamp, &yearstart, &actual); @@ -171,5 +181,7 @@ TEST_F(clocktimeTest, AlwaysInLimit) { diff = ~diff + 1; ASSERT_LE(diff, (183u * SECSPERDAY)); } + } + } } } diff --git a/util/Makefile.am b/util/Makefile.am index 01cb3ba0d..a585ec2b7 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -14,7 +14,7 @@ EXTRA_PROGRAMS= audio-pcm byteorder hist jitter kern longsize \ INCLUDES = -I$(top_srcdir)/include INCLUDES += -I$(top_srcdir)/lib/isc/include -INCLUDES += -I$(top_srcdir)/lib/isc/nothreads/include +INCLUDES += -I$(top_srcdir)/lib/isc/@LIBISC_PTHREADS_NOTHREADS@/include INCLUDES += -I$(top_srcdir)/lib/isc/unix/include INCLUDES += $(LIBOPTS_CFLAGS) @@ -22,10 +22,11 @@ AM_CFLAGS = @CFLAGS_NTP@ AM_CPPFLAGS = @CPPFLAGS_NTP@ # LDADD might need RESLIB and ADJLIB -LDADD= ../libntp/libntp.a +LDADD= ../libntp/libntp.a @LDADD_LIBNTP@ @PTHREAD_LIBS@ tg2_LDADD= $(LIBM) +ntp_keygen_LDADD = version.o $(LIBOPTS_LDADD) ../libntp/libntp.a @LDADD_LIBNTP@ +ntp_keygen_LDADD += @PTHREAD_LIBS@ @LCRYPTO@ ntp_keygen_SOURCES = ntp-keygen.c ntp-keygen-opts.c ntp-keygen-opts.h -ntp_keygen_LDADD= version.o $(LIBOPTS_LDADD) ../libntp/libntp.a @LCRYPTO@ ETAGS_ARGS= Makefile.am #EXTRA_DIST= README TAGS @@ -65,11 +66,10 @@ $(srcdir)/ntp-keygen-opts.texi: $(srcdir)/ntp-keygen-opts.def $(std_def_list) jitter_SOURCES= jitter.c jitter.h jitter_LDADD= -check-libntp: FRC - cd ../libntp && $(MAKE) - FRC: +check-libntp: FRC ../libntp/libntp.a + ../libntp/libntp.a: cd ../libntp && $(MAKE) @@ -79,7 +79,9 @@ kern.o: kern.c $(top_srcdir)/sntp/version: cd $(top_srcdir)/sntp && $(MAKE) version -version.o: $(ntpq_OBJECTS) ../libntp/libntp.a Makefile $(top_srcdir)/sntp/version +$(PROGRAMS): version.o + +version.o: $(ntp_keygen_OBJECTS) ../libntp/libntp.a Makefile $(top_srcdir)/sntp/version env CSET=`cat $(top_srcdir)/sntp/version` $(top_builddir)/scripts/mkver ntp-keygen $(COMPILE) -c version.c diff --git a/util/ntp-keygen.c b/util/ntp-keygen.c index a008df160..516a8e96a 100644 --- a/util/ntp-keygen.c +++ b/util/ntp-keygen.c @@ -112,7 +112,6 @@ */ #define MD5KEYS 10 /* number of keys generated of each type */ #define MD5SIZE 20 /* maximum key size */ -#define JAN_1970 2208988800UL /* NTP seconds */ #define DAY ((long)60*60*24) /* one day in seconds */ #define YEAR ((long)365) /* one year in days */ #define MAXFILENAME 256 /* max file name length */