aboutsummaryrefslogtreecommitdiff
path: root/contrib/ntp/libntp/lib/isc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/ntp/libntp/lib/isc')
-rw-r--r--contrib/ntp/libntp/lib/isc/assertions.c139
-rw-r--r--contrib/ntp/libntp/lib/isc/backtrace-emptytbl.c34
-rw-r--r--contrib/ntp/libntp/lib/isc/backtrace.c285
-rw-r--r--contrib/ntp/libntp/lib/isc/buffer.c489
-rw-r--r--contrib/ntp/libntp/lib/isc/error.c106
-rw-r--r--contrib/ntp/libntp/lib/isc/event.c86
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/app.h375
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/assertions.h126
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/backtrace.h131
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/bind9.h30
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/boolean.h31
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/buffer.h904
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/error.h63
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/event.h121
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/eventclass.h53
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/file.h304
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/formatcheck.h40
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/hash.h185
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/interfaceiter.h138
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/lang.h33
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/lib.h50
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/list.h197
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/log.h914
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/magic.h41
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/md5.h83
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/msgcat.h131
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/msgs.h195
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/namespace.h171
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/netaddr.h180
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/netscope.h43
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/ondestroy.h116
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/platform.h40
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/print.h87
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/random.h62
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/region.h99
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/result.h109
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/resultclass.h51
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/sha1.h68
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/sockaddr.h241
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/socket.h1168
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/stdio.h77
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/string.h249
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/task.h796
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/timer.h431
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/types.h129
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/util.h238
-rw-r--r--contrib/ntp/libntp/lib/isc/include/isc/xml.h41
-rw-r--r--contrib/ntp/libntp/lib/isc/inet_ntop.c203
-rw-r--r--contrib/ntp/libntp/lib/isc/inet_pton.c215
-rw-r--r--contrib/ntp/libntp/lib/isc/lib.c103
-rw-r--r--contrib/ntp/libntp/lib/isc/log.c1767
-rw-r--r--contrib/ntp/libntp/lib/isc/md5.c277
-rw-r--r--contrib/ntp/libntp/lib/isc/netaddr.c435
-rw-r--r--contrib/ntp/libntp/lib/isc/netscope.c76
-rw-r--r--contrib/ntp/libntp/lib/isc/nls/msgcat.c131
-rw-r--r--contrib/ntp/libntp/lib/isc/nothreads/condition.c24
-rw-r--r--contrib/ntp/libntp/lib/isc/nothreads/include/isc/condition.h59
-rw-r--r--contrib/ntp/libntp/lib/isc/nothreads/include/isc/mutex.h39
-rw-r--r--contrib/ntp/libntp/lib/isc/nothreads/include/isc/once.h32
-rw-r--r--contrib/ntp/libntp/lib/isc/nothreads/include/isc/thread.h35
-rw-r--r--contrib/ntp/libntp/lib/isc/nothreads/thread.c28
-rw-r--r--contrib/ntp/libntp/lib/isc/ondestroy.c85
-rw-r--r--contrib/ntp/libntp/lib/isc/pthreads/condition.c74
-rw-r--r--contrib/ntp/libntp/lib/isc/pthreads/include/isc/condition.h65
-rw-r--r--contrib/ntp/libntp/lib/isc/pthreads/include/isc/mutex.h145
-rw-r--r--contrib/ntp/libntp/lib/isc/pthreads/include/isc/once.h50
-rw-r--r--contrib/ntp/libntp/lib/isc/pthreads/include/isc/thread.h60
-rw-r--r--contrib/ntp/libntp/lib/isc/pthreads/mutex.c284
-rw-r--r--contrib/ntp/libntp/lib/isc/pthreads/thread.c76
-rw-r--r--contrib/ntp/libntp/lib/isc/random.c111
-rw-r--r--contrib/ntp/libntp/lib/isc/result.c214
-rw-r--r--contrib/ntp/libntp/lib/isc/sha1.c354
-rw-r--r--contrib/ntp/libntp/lib/isc/sockaddr.c510
-rw-r--r--contrib/ntp/libntp/lib/isc/task.c1813
-rw-r--r--contrib/ntp/libntp/lib/isc/task_p.h39
-rw-r--r--contrib/ntp/libntp/lib/isc/tsmemcmp.c55
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/dir.c256
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/errno2result.c122
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/errno2result.h41
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/file.c544
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/ifiter_getifaddrs.c283
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/ifiter_ioctl.c1032
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/ifiter_sysctl.c321
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/include/isc/dir.h94
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/include/isc/int.h55
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/include/isc/net.h364
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/include/isc/offset.h46
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/include/isc/stat.h52
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/include/isc/stdtime.h64
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/include/isc/strerror.h45
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/include/isc/time.h334
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/interfaceiter.c327
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/net.c523
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/stdio.c129
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/stdtime.c86
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/strerror.c76
-rw-r--r--contrib/ntp/libntp/lib/isc/unix/time.c420
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/condition.c258
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/condition.h67
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/dir.h83
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/int.h58
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/ipv6.h124
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/mutex.h55
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/net.h374
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/offset.h44
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/once.h43
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/platform.h117
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/stat.h68
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/stdtime.h62
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/strerror.h42
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/thread.h100
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/time.h291
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/include/isc/win32os.h71
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/interfaceiter.c807
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/net.c339
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/once.c54
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/stdtime.c37
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/strerror.c493
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/thread.c94
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/time.c320
-rw-r--r--contrib/ntp/libntp/lib/isc/win32/win32os.c101
121 files changed, 26355 insertions, 0 deletions
diff --git a/contrib/ntp/libntp/lib/isc/assertions.c b/contrib/ntp/libntp/lib/isc/assertions.c
new file mode 100644
index 000000000000..31c4fe7c9f27
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/assertions.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: assertions.c,v 1.26 2009/09/29 15:06:07 fdupont Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <isc/assertions.h>
+#include <isc/backtrace.h>
+#include <isc/msgs.h>
+#include <isc/result.h>
+
+/*
+ * The maximum number of stack frames to dump on assertion failure.
+ */
+#ifndef BACKTRACE_MAXFRAME
+#define BACKTRACE_MAXFRAME 128
+#endif
+
+/*%
+ * Forward.
+ */
+static void
+default_callback(const char *, int, isc_assertiontype_t, const char *);
+
+static isc_assertioncallback_t isc_assertion_failed_cb = default_callback;
+
+/*%
+ * Public.
+ */
+
+/*% assertion failed handler */
+/* coverity[+kill] */
+void
+isc_assertion_failed(const char *file, int line, isc_assertiontype_t type,
+ const char *cond)
+{
+ isc_assertion_failed_cb(file, line, type, cond);
+ abort();
+ /* NOTREACHED */
+}
+
+/*% Set callback. */
+void
+isc_assertion_setcallback(isc_assertioncallback_t cb) {
+ if (cb == NULL)
+ isc_assertion_failed_cb = default_callback;
+ else
+ isc_assertion_failed_cb = cb;
+}
+
+/*% Type to Text */
+const char *
+isc_assertion_typetotext(isc_assertiontype_t type) {
+ const char *result;
+
+ /*
+ * These strings have purposefully not been internationalized
+ * because they are considered to essentially be keywords of
+ * the ISC development environment.
+ */
+ switch (type) {
+ case isc_assertiontype_require:
+ result = "REQUIRE";
+ break;
+ case isc_assertiontype_ensure:
+ result = "ENSURE";
+ break;
+ case isc_assertiontype_insist:
+ result = "INSIST";
+ break;
+ case isc_assertiontype_invariant:
+ result = "INVARIANT";
+ break;
+ default:
+ result = NULL;
+ }
+ return (result);
+}
+
+/*
+ * Private.
+ */
+
+static void
+default_callback(const char *file, int line, isc_assertiontype_t type,
+ const char *cond)
+{
+ void *tracebuf[BACKTRACE_MAXFRAME];
+ int i, nframes;
+ const char *logsuffix = ".";
+ const char *fname;
+ isc_result_t result;
+
+ result = isc_backtrace_gettrace(tracebuf, BACKTRACE_MAXFRAME, &nframes);
+ if (result == ISC_R_SUCCESS && nframes > 0)
+ logsuffix = ", back trace";
+
+ fprintf(stderr, "%s:%d: %s(%s) %s%s\n",
+ file, line, isc_assertion_typetotext(type), cond,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"), logsuffix);
+ if (result == ISC_R_SUCCESS) {
+ for (i = 0; i < nframes; i++) {
+ unsigned long offset;
+
+ fname = NULL;
+ result = isc_backtrace_getsymbol(tracebuf[i], &fname,
+ &offset);
+ if (result == ISC_R_SUCCESS) {
+ fprintf(stderr, "#%d %p in %s()+0x%lx\n", i,
+ tracebuf[i], fname, offset);
+ } else {
+ fprintf(stderr, "#%d %p in ??\n", i,
+ tracebuf[i]);
+ }
+ }
+ }
+ fflush(stderr);
+}
diff --git a/contrib/ntp/libntp/lib/isc/backtrace-emptytbl.c b/contrib/ntp/libntp/lib/isc/backtrace-emptytbl.c
new file mode 100644
index 000000000000..bd534d60c8e2
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/backtrace-emptytbl.c
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: backtrace-emptytbl.c,v 1.3 2009/09/01 20:13:44 each Exp $ */
+
+/*! \file */
+
+/*
+ * This file defines an empty (default) symbol table used in backtrace.c
+ * If the application wants to have a complete symbol table, it should redefine
+ * isc__backtrace_symtable with the complete table in some way, and link the
+ * version of the library not including this definition
+ * (e.g. libisc-nosymbol.a).
+ */
+
+#include <config.h>
+
+#include <isc/backtrace.h>
+
+const int isc__backtrace_nsymbols = 0;
+const isc_backtrace_symmap_t isc__backtrace_symtable[] = { { NULL, "" } };
diff --git a/contrib/ntp/libntp/lib/isc/backtrace.c b/contrib/ntp/libntp/lib/isc/backtrace.c
new file mode 100644
index 000000000000..e0425e14f41c
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/backtrace.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: backtrace.c,v 1.3 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#ifdef HAVE_LIBCTRACE
+#include <execinfo.h>
+#endif
+
+#include <isc/backtrace.h>
+#include <isc/result.h>
+#include <isc/util.h>
+
+#ifdef ISC_PLATFORM_USEBACKTRACE
+/*
+ * Getting a back trace of a running process is tricky and highly platform
+ * dependent. Our current approach is as follows:
+ * 1. If the system library supports the "backtrace()" function, use it.
+ * 2. Otherwise, if the compiler is gcc and the architecture is x86_64 or IA64,
+ * then use gcc's (hidden) Unwind_Backtrace() function. Note that this
+ * function doesn't work for C programs on many other architectures.
+ * 3. Otherwise, if the architecture x86 or x86_64, try to unwind the stack
+ * frame following frame pointers. This assumes the executable binary
+ * compiled with frame pointers; this is not always true for x86_64 (rather,
+ * compiler optimizations often disable frame pointers). The validation
+ * checks in getnextframeptr() hopefully rejects bogus values stored in
+ * the RBP register in such a case. If the backtrace function itself crashes
+ * due to this problem, the whole package should be rebuilt with
+ * --disable-backtrace.
+ */
+#ifdef HAVE_LIBCTRACE
+#define BACKTRACE_LIBC
+#elif defined(__GNUC__) && (defined(__x86_64__) || defined(__ia64__))
+#define BACKTRACE_GCC
+#elif defined(__x86_64__) || defined(__i386__)
+#define BACKTRACE_X86STACK
+#else
+#define BACKTRACE_DISABLED
+#endif /* HAVE_LIBCTRACE */
+#else /* !ISC_PLATFORM_USEBACKTRACE */
+#define BACKTRACE_DISABLED
+#endif /* ISC_PLATFORM_USEBACKTRACE */
+
+#ifdef BACKTRACE_LIBC
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ int n;
+
+ /*
+ * Validate the arguments: intentionally avoid using REQUIRE().
+ * See notes in backtrace.h.
+ */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ /*
+ * backtrace(3) includes this function itself in the address array,
+ * which should be eliminated from the returned sequence.
+ */
+ n = backtrace(addrs, maxaddrs);
+ if (n < 2)
+ return (ISC_R_NOTFOUND);
+ n--;
+ memmove(addrs, &addrs[1], sizeof(void *) * n);
+ *nframes = n;
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_GCC)
+extern int _Unwind_Backtrace(void* fn, void* a);
+extern void* _Unwind_GetIP(void* ctx);
+
+typedef struct {
+ void **result;
+ int max_depth;
+ int skip_count;
+ int count;
+} trace_arg_t;
+
+static int
+btcallback(void *uc, void *opq) {
+ trace_arg_t *arg = (trace_arg_t *)opq;
+
+ if (arg->skip_count > 0)
+ arg->skip_count--;
+ else
+ arg->result[arg->count++] = (void *)_Unwind_GetIP(uc);
+ if (arg->count == arg->max_depth)
+ return (5); /* _URC_END_OF_STACK */
+
+ return (0); /* _URC_NO_REASON */
+}
+
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ trace_arg_t arg;
+
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ arg.skip_count = 1;
+ arg.result = addrs;
+ arg.max_depth = maxaddrs;
+ arg.count = 0;
+ _Unwind_Backtrace(btcallback, &arg);
+
+ *nframes = arg.count;
+
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_X86STACK)
+#ifdef __x86_64__
+static unsigned long
+getrbp() {
+ __asm("movq %rbp, %rax\n");
+}
+#endif
+
+static void **
+getnextframeptr(void **sp) {
+ void **newsp = (void **)*sp;
+
+ /*
+ * Perform sanity check for the new frame pointer, derived from
+ * google glog. This can actually be bogus depending on compiler.
+ */
+
+ /* prohibit the stack frames from growing downwards */
+ if (newsp <= sp)
+ return (NULL);
+
+ /* A heuristics to reject "too large" frame: this actually happened. */
+ if ((char *)newsp - (char *)sp > 100000)
+ return (NULL);
+
+ /*
+ * Not sure if other checks used in glog are needed at this moment.
+ * For our purposes we don't have to consider non-contiguous frames,
+ * for example.
+ */
+
+ return (newsp);
+}
+
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ int i = 0;
+ void **sp;
+
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+#ifdef __x86_64__
+ sp = (void **)getrbp();
+ if (sp == NULL)
+ return (ISC_R_NOTFOUND);
+ /*
+ * sp is the frame ptr of this function itself due to the call to
+ * getrbp(), so need to unwind one frame for consistency.
+ */
+ sp = getnextframeptr(sp);
+#else
+ /*
+ * i386: the frame pointer is stored 2 words below the address for the
+ * first argument. Note that the body of this function cannot be
+ * inlined since it depends on the address of the function argument.
+ */
+ sp = (void **)&addrs - 2;
+#endif
+
+ while (sp != NULL && i < maxaddrs) {
+ addrs[i++] = *(sp + 1);
+ sp = getnextframeptr(sp);
+ }
+
+ *nframes = i;
+
+ return (ISC_R_SUCCESS);
+}
+#elif defined(BACKTRACE_DISABLED)
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes) {
+ /* Argument validation: see above. */
+ if (addrs == NULL || nframes == NULL)
+ return (ISC_R_FAILURE);
+
+ UNUSED(maxaddrs);
+
+ return (ISC_R_NOTIMPLEMENTED);
+}
+#endif
+
+isc_result_t
+isc_backtrace_getsymbolfromindex(int idx, const void **addrp,
+ const char **symbolp)
+{
+ REQUIRE(addrp != NULL && *addrp == NULL);
+ REQUIRE(symbolp != NULL && *symbolp == NULL);
+
+ if (idx < 0 || idx >= isc__backtrace_nsymbols)
+ return (ISC_R_RANGE);
+
+ *addrp = isc__backtrace_symtable[idx].addr;
+ *symbolp = isc__backtrace_symtable[idx].symbol;
+ return (ISC_R_SUCCESS);
+}
+
+static int
+symtbl_compare(const void *addr, const void *entryarg) {
+ const isc_backtrace_symmap_t *entry = entryarg;
+ const isc_backtrace_symmap_t *end =
+ &isc__backtrace_symtable[isc__backtrace_nsymbols - 1];
+
+ if (isc__backtrace_nsymbols == 1 || entry == end) {
+ if (addr >= entry->addr) {
+ /*
+ * If addr is equal to or larger than that of the last
+ * entry of the table, we cannot be sure if this is
+ * within a valid range so we consider it valid.
+ */
+ return (0);
+ }
+ return (-1);
+ }
+
+ /* entry + 1 is a valid entry from now on. */
+ if (addr < entry->addr)
+ return (-1);
+ else if (addr >= (entry + 1)->addr)
+ return (1);
+ return (0);
+}
+
+isc_result_t
+isc_backtrace_getsymbol(const void *addr, const char **symbolp,
+ unsigned long *offsetp)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_backtrace_symmap_t *found;
+
+ /*
+ * Validate the arguments: intentionally avoid using REQUIRE().
+ * See notes in backtrace.h.
+ */
+ if (symbolp == NULL || *symbolp != NULL || offsetp == NULL)
+ return (ISC_R_FAILURE);
+
+ if (isc__backtrace_nsymbols < 1)
+ return (ISC_R_NOTFOUND);
+
+ /*
+ * Search the table for the entry that meets:
+ * entry.addr <= addr < next_entry.addr.
+ */
+ found = bsearch(addr, isc__backtrace_symtable, isc__backtrace_nsymbols,
+ sizeof(isc__backtrace_symtable[0]), symtbl_compare);
+ if (found == NULL)
+ result = ISC_R_NOTFOUND;
+ else {
+ *symbolp = found->symbol;
+ *offsetp = (u_long)((const char *)addr - (char *)found->addr);
+ }
+
+ return (result);
+}
diff --git a/contrib/ntp/libntp/lib/isc/buffer.c b/contrib/ntp/libntp/lib/isc/buffer.c
new file mode 100644
index 000000000000..6a50985c74ab
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/buffer.c
@@ -0,0 +1,489 @@
+/*
+ * Copyright (C) 2004-2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: buffer.c,v 1.49 2008/09/25 04:02:39 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isc/buffer.h>
+#include <isc/mem.h>
+#include <isc/region.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+void
+isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length) {
+ /*
+ * Make 'b' refer to the 'length'-byte region starting at 'base'.
+ * XXXDCL see the comment in buffer.h about base being const.
+ */
+
+ REQUIRE(b != NULL);
+
+ ISC__BUFFER_INIT(b, base, length);
+}
+
+void
+isc__buffer_initnull(isc_buffer_t *b) {
+ /*
+ * Initialize a new buffer which has no backing store. This can
+ * later be grown as needed and swapped in place.
+ */
+
+ ISC__BUFFER_INIT(b, NULL, 0);
+}
+
+void
+isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length) {
+ /*
+ * Re-initialize the buffer enough to reconfigure the base of the
+ * buffer. We will swap in the new buffer, after copying any
+ * data we contain into the new buffer and adjusting all of our
+ * internal pointers.
+ *
+ * The buffer must not be smaller than the length of the original
+ * buffer.
+ */
+ REQUIRE(b->length <= length);
+ REQUIRE(base != NULL);
+
+ (void)memmove(base, b->base, b->length);
+ b->base = base;
+ b->length = length;
+}
+
+void
+isc__buffer_invalidate(isc_buffer_t *b) {
+ /*
+ * Make 'b' an invalid buffer.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(!ISC_LINK_LINKED(b, link));
+ REQUIRE(b->mctx == NULL);
+
+ ISC__BUFFER_INVALIDATE(b);
+}
+
+void
+isc__buffer_region(isc_buffer_t *b, isc_region_t *r) {
+ /*
+ * Make 'r' refer to the region of 'b'.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(r != NULL);
+
+ ISC__BUFFER_REGION(b, r);
+}
+
+void
+isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r) {
+ /*
+ * Make 'r' refer to the used region of 'b'.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(r != NULL);
+
+ ISC__BUFFER_USEDREGION(b, r);
+}
+
+void
+isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r) {
+ /*
+ * Make 'r' refer to the available region of 'b'.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(r != NULL);
+
+ ISC__BUFFER_AVAILABLEREGION(b, r);
+}
+
+void
+isc__buffer_add(isc_buffer_t *b, unsigned int n) {
+ /*
+ * Increase the 'used' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used + n <= b->length);
+
+ ISC__BUFFER_ADD(b, n);
+}
+
+void
+isc__buffer_subtract(isc_buffer_t *b, unsigned int n) {
+ /*
+ * Decrease the 'used' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used >= n);
+
+ ISC__BUFFER_SUBTRACT(b, n);
+}
+
+void
+isc__buffer_clear(isc_buffer_t *b) {
+ /*
+ * Make the used region empty.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+
+ ISC__BUFFER_CLEAR(b);
+}
+
+void
+isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r) {
+ /*
+ * Make 'r' refer to the consumed region of 'b'.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(r != NULL);
+
+ ISC__BUFFER_CONSUMEDREGION(b, r);
+}
+
+void
+isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r) {
+ /*
+ * Make 'r' refer to the remaining region of 'b'.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(r != NULL);
+
+ ISC__BUFFER_REMAININGREGION(b, r);
+}
+
+void
+isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r) {
+ /*
+ * Make 'r' refer to the active region of 'b'.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(r != NULL);
+
+ ISC__BUFFER_ACTIVEREGION(b, r);
+}
+
+void
+isc__buffer_setactive(isc_buffer_t *b, unsigned int n) {
+ /*
+ * Sets the end of the active region 'n' bytes after current.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->current + n <= b->used);
+
+ ISC__BUFFER_SETACTIVE(b, n);
+}
+
+void
+isc__buffer_first(isc_buffer_t *b) {
+ /*
+ * Make the consumed region empty.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+
+ ISC__BUFFER_FIRST(b);
+}
+
+void
+isc__buffer_forward(isc_buffer_t *b, unsigned int n) {
+ /*
+ * Increase the 'consumed' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->current + n <= b->used);
+
+ ISC__BUFFER_FORWARD(b, n);
+}
+
+void
+isc__buffer_back(isc_buffer_t *b, unsigned int n) {
+ /*
+ * Decrease the 'consumed' region of 'b' by 'n' bytes.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(n <= b->current);
+
+ ISC__BUFFER_BACK(b, n);
+}
+
+void
+isc_buffer_compact(isc_buffer_t *b) {
+ unsigned int length;
+ void *src;
+
+ /*
+ * Compact the used region by moving the remaining region so it occurs
+ * at the start of the buffer. The used region is shrunk by the size
+ * of the consumed region, and the consumed region is then made empty.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+
+ src = isc_buffer_current(b);
+ length = isc_buffer_remaininglength(b);
+ (void)memmove(b->base, src, (size_t)length);
+
+ if (b->active > b->current)
+ b->active -= b->current;
+ else
+ b->active = 0;
+ b->current = 0;
+ b->used = length;
+}
+
+isc_uint8_t
+isc_buffer_getuint8(isc_buffer_t *b) {
+ unsigned char *cp;
+ isc_uint8_t result;
+
+ /*
+ * Read an unsigned 8-bit integer from 'b' and return it.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 1);
+
+ cp = isc_buffer_current(b);
+ b->current += 1;
+ result = ((isc_uint8_t)(cp[0]));
+
+ return (result);
+}
+
+void
+isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val) {
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used + 1 <= b->length);
+
+ ISC__BUFFER_PUTUINT8(b, val);
+}
+
+isc_uint16_t
+isc_buffer_getuint16(isc_buffer_t *b) {
+ unsigned char *cp;
+ isc_uint16_t result;
+
+ /*
+ * Read an unsigned 16-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 2);
+
+ cp = isc_buffer_current(b);
+ b->current += 2;
+ result = ((unsigned int)(cp[0])) << 8;
+ result |= ((unsigned int)(cp[1]));
+
+ return (result);
+}
+
+void
+isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val) {
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used + 2 <= b->length);
+
+ ISC__BUFFER_PUTUINT16(b, val);
+}
+
+void
+isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val) {
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used + 3 <= b->length);
+
+ ISC__BUFFER_PUTUINT24(b, val);
+}
+
+isc_uint32_t
+isc_buffer_getuint32(isc_buffer_t *b) {
+ unsigned char *cp;
+ isc_uint32_t result;
+
+ /*
+ * Read an unsigned 32-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 4);
+
+ cp = isc_buffer_current(b);
+ b->current += 4;
+ result = ((unsigned int)(cp[0])) << 24;
+ result |= ((unsigned int)(cp[1])) << 16;
+ result |= ((unsigned int)(cp[2])) << 8;
+ result |= ((unsigned int)(cp[3]));
+
+ return (result);
+}
+
+void
+isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val) {
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used + 4 <= b->length);
+
+ ISC__BUFFER_PUTUINT32(b, val);
+}
+
+isc_uint64_t
+isc_buffer_getuint48(isc_buffer_t *b) {
+ unsigned char *cp;
+ isc_uint64_t result;
+
+ /*
+ * Read an unsigned 48-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ */
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used - b->current >= 6);
+
+ cp = isc_buffer_current(b);
+ b->current += 6;
+ result = ((isc_int64_t)(cp[0])) << 40;
+ result |= ((isc_int64_t)(cp[1])) << 32;
+ result |= ((isc_int64_t)(cp[2])) << 24;
+ result |= ((isc_int64_t)(cp[3])) << 16;
+ result |= ((isc_int64_t)(cp[4])) << 8;
+ result |= ((isc_int64_t)(cp[5]));
+
+ return (result);
+}
+
+void
+isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val) {
+ isc_uint16_t valhi;
+ isc_uint32_t vallo;
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used + 6 <= b->length);
+
+ valhi = (isc_uint16_t)(val >> 32);
+ vallo = (isc_uint32_t)(val & 0xFFFFFFFF);
+ ISC__BUFFER_PUTUINT16(b, valhi);
+ ISC__BUFFER_PUTUINT32(b, vallo);
+}
+
+void
+isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
+ unsigned int length)
+{
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(b->used + length <= b->length);
+
+ ISC__BUFFER_PUTMEM(b, base, length);
+}
+
+void
+isc__buffer_putstr(isc_buffer_t *b, const char *source) {
+ size_t l;
+ unsigned char *cp;
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(source != NULL);
+
+ /*
+ * Do not use ISC__BUFFER_PUTSTR(), so strlen is only done once.
+ */
+ l = strlen(source);
+
+ REQUIRE(l <= isc_buffer_availablelength(b));
+
+ cp = isc_buffer_used(b);
+ memcpy(cp, source, l);
+ b->used += (u_int)l; /* checked above - no overflow here */
+}
+
+isc_result_t
+isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r) {
+ unsigned char *base;
+ unsigned int available;
+
+ REQUIRE(ISC_BUFFER_VALID(b));
+ REQUIRE(r != NULL);
+
+ /*
+ * XXXDCL
+ */
+ base = isc_buffer_used(b);
+ available = isc_buffer_availablelength(b);
+ if (r->length > available)
+ return (ISC_R_NOSPACE);
+ memcpy(base, r->base, r->length);
+ b->used += r->length;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
+ unsigned int length)
+{
+ isc_buffer_t *dbuf;
+
+ REQUIRE(dynbuffer != NULL);
+ REQUIRE(*dynbuffer == NULL);
+
+ dbuf = isc_mem_get(mctx, length + sizeof(isc_buffer_t));
+ if (dbuf == NULL)
+ return (ISC_R_NOMEMORY);
+
+ isc_buffer_init(dbuf, ((unsigned char *)dbuf) + sizeof(isc_buffer_t),
+ length);
+ dbuf->mctx = mctx;
+
+ *dynbuffer = dbuf;
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_buffer_free(isc_buffer_t **dynbuffer) {
+ unsigned int real_length;
+ isc_buffer_t *dbuf;
+ isc_mem_t *mctx;
+
+ REQUIRE(dynbuffer != NULL);
+ REQUIRE(ISC_BUFFER_VALID(*dynbuffer));
+ REQUIRE((*dynbuffer)->mctx != NULL);
+
+ dbuf = *dynbuffer;
+ *dynbuffer = NULL; /* destroy external reference */
+
+ real_length = dbuf->length + sizeof(isc_buffer_t);
+ mctx = dbuf->mctx;
+ dbuf->mctx = NULL;
+ isc_buffer_invalidate(dbuf);
+
+ isc_mem_put(mctx, dbuf, real_length);
+}
diff --git a/contrib/ntp/libntp/lib/isc/error.c b/contrib/ntp/libntp/lib/isc/error.c
new file mode 100644
index 000000000000..095100a7c943
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/error.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: error.c,v 1.21 2007/06/19 23:47:17 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <isc/error.h>
+#include <isc/msgs.h>
+
+/*% Default unexpected callback. */
+static void
+default_unexpected_callback(const char *, int, const char *, va_list)
+ ISC_FORMAT_PRINTF(3, 0);
+
+/*% Default fatal callback. */
+static void
+default_fatal_callback(const char *, int, const char *, va_list)
+ ISC_FORMAT_PRINTF(3, 0);
+
+/*% unexpected_callback */
+static isc_errorcallback_t unexpected_callback = default_unexpected_callback;
+static isc_errorcallback_t fatal_callback = default_fatal_callback;
+
+void
+isc_error_setunexpected(isc_errorcallback_t cb) {
+ if (cb == NULL)
+ unexpected_callback = default_unexpected_callback;
+ else
+ unexpected_callback = cb;
+}
+
+void
+isc_error_setfatal(isc_errorcallback_t cb) {
+ if (cb == NULL)
+ fatal_callback = default_fatal_callback;
+ else
+ fatal_callback = cb;
+}
+
+void
+isc_error_unexpected(const char *file, int line, const char *format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ (unexpected_callback)(file, line, format, args);
+ va_end(args);
+}
+
+void
+isc_error_fatal(const char *file, int line, const char *format, ...) {
+ va_list args;
+
+ va_start(args, format);
+ (fatal_callback)(file, line, format, args);
+ va_end(args);
+ abort();
+}
+
+void
+isc_error_runtimecheck(const char *file, int line, const char *expression) {
+ isc_error_fatal(file, line, "RUNTIME_CHECK(%s) %s", expression,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+}
+
+static void
+default_unexpected_callback(const char *file, int line, const char *format,
+ va_list args)
+{
+ fprintf(stderr, "%s:%d: ", file, line);
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
+
+static void
+default_fatal_callback(const char *file, int line, const char *format,
+ va_list args)
+{
+ fprintf(stderr, "%s:%d: %s: ", file, line,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FATALERROR, "fatal error"));
+ vfprintf(stderr, format, args);
+ fprintf(stderr, "\n");
+ fflush(stderr);
+}
diff --git a/contrib/ntp/libntp/lib/isc/event.c b/contrib/ntp/libntp/lib/isc/event.c
new file mode 100644
index 000000000000..e97961682656
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/event.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: event.c,v 1.21 2007/06/19 23:47:17 tbox Exp $ */
+
+/*!
+ * \file
+ * \author Principal Author: Bob Halley
+ */
+
+#include <config.h>
+
+#include <isc/event.h>
+#include <isc/mem.h>
+#include <isc/util.h>
+
+/***
+ *** Events.
+ ***/
+
+static void
+destroy(isc_event_t *event) {
+ isc_mem_put(event->ev_destroy_arg, event, event->ev_size);
+}
+
+isc_event_t *
+isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type,
+ isc_taskaction_t action, const void *arg, size_t size)
+{
+ isc_event_t *event;
+ void *deconst_arg;
+
+ REQUIRE(size >= sizeof(struct isc_event));
+ REQUIRE(action != NULL);
+
+ event = isc_mem_get(mctx, size);
+ if (event == NULL)
+ return (NULL);
+
+ /*
+ * Removing the const attribute from "arg" is the best of two
+ * evils here. If the event->ev_arg member is made const, then
+ * it affects a great many users of the task/event subsystem
+ * which are not passing in an "arg" which starts its life as
+ * const. Changing isc_event_allocate() and isc_task_onshutdown()
+ * to not have "arg" prototyped as const (which is quite legitimate,
+ * because neither of those functions modify arg) can cause
+ * compiler whining anytime someone does want to use a const
+ * arg that they themselves never modify, such as with
+ * gcc -Wwrite-strings and using a string "arg".
+ */
+ DE_CONST(arg, deconst_arg);
+
+ ISC_EVENT_INIT(event, size, 0, NULL, type, action, deconst_arg,
+ sender, destroy, mctx);
+
+ return (event);
+}
+
+void
+isc_event_free(isc_event_t **eventp) {
+ isc_event_t *event;
+
+ REQUIRE(eventp != NULL);
+ event = *eventp;
+ REQUIRE(event != NULL);
+
+ if (event->ev_destroy != NULL)
+ (event->ev_destroy)(event);
+
+ *eventp = NULL;
+}
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/app.h b/contrib/ntp/libntp/lib/isc/include/isc/app.h
new file mode 100644
index 000000000000..e0be79063709
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/app.h
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: app.h,v 1.11 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISC_APP_H
+#define ISC_APP_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/app.h
+ * \brief ISC Application Support
+ *
+ * Dealing with program termination can be difficult, especially in a
+ * multithreaded program. The routines in this module help coordinate
+ * the shutdown process. They are used as follows by the initial (main)
+ * thread of the application:
+ *
+ *\li isc_app_start(); Call very early in main(), before
+ * any other threads have been created.
+ *
+ *\li isc_app_run(); This will post any on-run events,
+ * and then block until application
+ * shutdown is requested. A shutdown
+ * request is made by calling
+ * isc_app_shutdown(), or by sending
+ * SIGINT or SIGTERM to the process.
+ * After isc_app_run() returns, the
+ * application should shutdown itself.
+ *
+ *\li isc_app_finish(); Call very late in main().
+ *
+ * Applications that want to use SIGHUP/isc_app_reload() to trigger reloading
+ * should check the result of isc_app_run() and call the reload routine if
+ * the result is ISC_R_RELOAD. They should then call isc_app_run() again
+ * to resume waiting for reload or termination.
+ *
+ * Use of this module is not required. In particular, isc_app_start() is
+ * NOT an ISC library initialization routine.
+ *
+ * This module also supports per-thread 'application contexts'. With this
+ * mode, a thread-based application will have a separate context, in which
+ * it uses other ISC library services such as tasks or timers. Signals are
+ * not caught in this mode, so that the application can handle the signals
+ * in its preferred way.
+ *
+ * \li MP:
+ * Clients must ensure that isc_app_start(), isc_app_run(), and
+ * isc_app_finish() are called at most once. isc_app_shutdown()
+ * is safe to use by any thread (provided isc_app_start() has been
+ * called previously).
+ *
+ * The same note applies to isc_app_ctxXXX() functions, but in this case
+ * it's a per-thread restriction. For example, a thread with an
+ * application context must ensure that isc_app_ctxstart() with the
+ * context is called at most once.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * None.
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+#include <isc/eventclass.h>
+#include <isc/lang.h>
+#include <isc/magic.h>
+#include <isc/result.h>
+
+/***
+ *** Types
+ ***/
+
+typedef isc_event_t isc_appevent_t;
+
+#define ISC_APPEVENT_FIRSTEVENT (ISC_EVENTCLASS_APP + 0)
+#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 1)
+#define ISC_APPEVENT_LASTEVENT (ISC_EVENTCLASS_APP + 65535)
+
+/*%
+ * app module methods. Only app driver implementations use this structure.
+ * Other clients should use the top-level interfaces (i.e., isc_app_xxx
+ * functions). magic must be ISCAPI_APPMETHODS_MAGIC.
+ */
+typedef struct isc_appmethods {
+ void (*ctxdestroy)(isc_appctx_t **ctxp);
+ isc_result_t (*ctxstart)(isc_appctx_t *ctx);
+ isc_result_t (*ctxrun)(isc_appctx_t *ctx);
+ isc_result_t (*ctxsuspend)(isc_appctx_t *ctx);
+ isc_result_t (*ctxshutdown)(isc_appctx_t *ctx);
+ void (*ctxfinish)(isc_appctx_t *ctx);
+ void (*settaskmgr)(isc_appctx_t *ctx,
+ isc_taskmgr_t *timermgr);
+ void (*setsocketmgr)(isc_appctx_t *ctx,
+ isc_socketmgr_t *timermgr);
+ void (*settimermgr)(isc_appctx_t *ctx,
+ isc_timermgr_t *timermgr);
+} isc_appmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of an application context
+ * implementation's version of an isc_appctx_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. app implementations
+ * may change the structure. 'magic' must be ISCAPI_APPCTX_MAGIC for any
+ * of the isc_app_ routines to work. app implementations must maintain
+ * all app context invariants.
+ */
+struct isc_appctx {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_appmethods_t *methods;
+};
+
+#define ISCAPI_APPCTX_MAGIC ISC_MAGIC('A','a','p','c')
+#define ISCAPI_APPCTX_VALID(c) ((c) != NULL && \
+ (c)->magic == ISCAPI_APPCTX_MAGIC)
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_app_ctxstart(isc_appctx_t *ctx);
+
+isc_result_t
+isc_app_start(void);
+/*!<
+ * \brief Start an ISC library application.
+ *
+ * Notes:
+ * This call should be made before any other ISC library call, and as
+ * close to the beginning of the application as possible.
+ *
+ * Requires:
+ * 'ctx' is a valid application context (for app_ctxstart()).
+ */
+
+isc_result_t
+isc_app_onrun(isc_mem_t *mctx, isc_task_t *task, isc_taskaction_t action,
+ void *arg);
+/*!<
+ * \brief Request delivery of an event when the application is run.
+ *
+ * Requires:
+ *\li isc_app_start() has been called.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * ISC_R_NOMEMORY
+ */
+
+isc_result_t
+isc_app_ctxrun(isc_appctx_t *ctx);
+
+isc_result_t
+isc_app_run(void);
+/*!<
+ * \brief Run an ISC library application.
+ *
+ * Notes:
+ *\li The caller (typically the initial thread of an application) will
+ * block until shutdown is requested. When the call returns, the
+ * caller should start shutting down the application.
+ *
+ * Requires:
+ *\li isc_app_[ctx]start() has been called.
+ *
+ * Ensures:
+ *\li Any events requested via isc_app_onrun() will have been posted (in
+ * FIFO order) before isc_app_run() blocks.
+ *\li 'ctx' is a valid application context (for app_ctxrun()).
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS Shutdown has been requested.
+ *\li ISC_R_RELOAD Reload has been requested.
+ */
+
+isc_result_t
+isc_app_ctxshutdown(isc_appctx_t *ctx);
+
+isc_result_t
+isc_app_shutdown(void);
+/*!<
+ * \brief Request application shutdown.
+ *
+ * Notes:
+ *\li It is safe to call isc_app_shutdown() multiple times. Shutdown will
+ * only be triggered once.
+ *
+ * Requires:
+ *\li isc_app_[ctx]run() has been called.
+ *\li 'ctx' is a valid application context (for app_ctxshutdown()).
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_app_ctxsuspend(isc_appctx_t *ctx);
+/*!<
+ * \brief This has the same behavior as isc_app_ctxsuspend().
+ */
+
+isc_result_t
+isc_app_reload(void);
+/*!<
+ * \brief Request application reload.
+ *
+ * Requires:
+ *\li isc_app_run() has been called.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_UNEXPECTED
+ */
+
+void
+isc_app_ctxfinish(isc_appctx_t *ctx);
+
+void
+isc_app_finish(void);
+/*!<
+ * \brief Finish an ISC library application.
+ *
+ * Notes:
+ *\li This call should be made at or near the end of main().
+ *
+ * Requires:
+ *\li isc_app_start() has been called.
+ *\li 'ctx' is a valid application context (for app_ctxfinish()).
+ *
+ * Ensures:
+ *\li Any resources allocated by isc_app_start() have been released.
+ */
+
+void
+isc_app_block(void);
+/*!<
+ * \brief Indicate that a blocking operation will be performed.
+ *
+ * Notes:
+ *\li If a blocking operation is in process, a call to isc_app_shutdown()
+ * or an external signal will abort the program, rather than allowing
+ * clean shutdown. This is primarily useful for reading user input.
+ *
+ * Requires:
+ * \li isc_app_start() has been called.
+ * \li No other blocking operations are in progress.
+ */
+
+void
+isc_app_unblock(void);
+/*!<
+ * \brief Indicate that a blocking operation is complete.
+ *
+ * Notes:
+ * \li When a blocking operation has completed, return the program to a
+ * state where a call to isc_app_shutdown() or an external signal will
+ * shutdown normally.
+ *
+ * Requires:
+ * \li isc_app_start() has been called.
+ * \li isc_app_block() has been called by the same thread.
+ */
+
+isc_result_t
+isc_appctx_create(isc_mem_t *mctx, isc_appctx_t **ctxp);
+/*!<
+ * \brief Create an application context.
+ *
+ * Requires:
+ *\li 'mctx' is a valid memory context.
+ *\li 'ctxp' != NULL && *ctxp == NULL.
+ */
+
+void
+isc_appctx_destroy(isc_appctx_t **ctxp);
+/*!<
+ * \brief Destroy an application context.
+ *
+ * Requires:
+ *\li '*ctxp' is a valid application context.
+ *
+ * Ensures:
+ *\li *ctxp == NULL.
+ */
+
+void
+isc_appctx_settaskmgr(isc_appctx_t *ctx, isc_taskmgr_t *taskmgr);
+/*!<
+ * \brief Associate a task manager with an application context.
+ *
+ * This must be done before running tasks within the application context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'taskmgr' is a valid task manager.
+ */
+
+void
+isc_appctx_setsocketmgr(isc_appctx_t *ctx, isc_socketmgr_t *socketmgr);
+/*!<
+ * \brief Associate a socket manager with an application context.
+ *
+ * This must be done before handling socket events within the application
+ * context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'socketmgr' is a valid socket manager.
+ */
+
+void
+isc_appctx_settimermgr(isc_appctx_t *ctx, isc_timermgr_t *timermgr);
+/*!<
+ * \brief Associate a socket timer with an application context.
+ *
+ * This must be done before handling timer events within the application
+ * context.
+ *
+ * Requires:
+ *\li 'ctx' is a valid application context.
+ *\li 'timermgr' is a valid timer manager.
+ */
+
+#ifdef USE_APPIMPREGISTER
+/*%<
+ * See isc_appctx_create() above.
+ */
+typedef isc_result_t
+(*isc_appctxcreatefunc_t)(isc_mem_t *mctx, isc_appctx_t **ctxp);
+
+isc_result_t
+isc_app_register(isc_appctxcreatefunc_t createfunc);
+/*%<
+ * Register a new application implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__app_register(void);
+/*%<
+ * A short cut function that specifies the application module in the ISC
+ * library for isc_app_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_APPIMPREGISTER */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_APP_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/assertions.h b/contrib/ntp/libntp/lib/isc/include/isc/assertions.h
new file mode 100644
index 000000000000..2c81b1ae9880
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/assertions.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * $Id: assertions.h,v 1.28 2009/09/29 23:48:04 tbox Exp $
+ */
+/*! \file isc/assertions.h
+ */
+
+#ifndef ISC_ASSERTIONS_H
+#define ISC_ASSERTIONS_H 1
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+ISC_LANG_BEGINDECLS
+
+/*% isc assertion type */
+typedef enum {
+ isc_assertiontype_require,
+ isc_assertiontype_ensure,
+ isc_assertiontype_insist,
+ isc_assertiontype_invariant
+} isc_assertiontype_t;
+
+typedef void (*isc_assertioncallback_t)(const char *, int, isc_assertiontype_t,
+ const char *);
+
+/* coverity[+kill] */
+ISC_PLATFORM_NORETURN_PRE
+void isc_assertion_failed(const char *, int, isc_assertiontype_t,
+ const char *) ISC_PLATFORM_NORETURN_POST;
+
+void
+isc_assertion_setcallback(isc_assertioncallback_t);
+
+const char *
+isc_assertion_typetotext(isc_assertiontype_t type);
+
+#if defined(ISC_CHECK_ALL) || defined(__COVERITY__)
+#define ISC_CHECK_REQUIRE 1
+#define ISC_CHECK_ENSURE 1
+#define ISC_CHECK_INSIST 1
+#define ISC_CHECK_INVARIANT 1
+#endif
+
+#if defined(ISC_CHECK_NONE) && !defined(__COVERITY__)
+#define ISC_CHECK_REQUIRE 0
+#define ISC_CHECK_ENSURE 0
+#define ISC_CHECK_INSIST 0
+#define ISC_CHECK_INVARIANT 0
+#endif
+
+#ifndef ISC_CHECK_REQUIRE
+#define ISC_CHECK_REQUIRE 1
+#endif
+
+#ifndef ISC_CHECK_ENSURE
+#define ISC_CHECK_ENSURE 1
+#endif
+
+#ifndef ISC_CHECK_INSIST
+#define ISC_CHECK_INSIST 1
+#endif
+
+#ifndef ISC_CHECK_INVARIANT
+#define ISC_CHECK_INVARIANT 1
+#endif
+
+#if ISC_CHECK_REQUIRE != 0
+#define ISC_REQUIRE(cond) \
+ ((void) ((cond) || \
+ ((isc_assertion_failed)(__FILE__, __LINE__, \
+ isc_assertiontype_require, \
+ #cond), 0)))
+#else
+#define ISC_REQUIRE(cond) ((void) 0)
+#endif /* ISC_CHECK_REQUIRE */
+
+#if ISC_CHECK_ENSURE != 0
+#define ISC_ENSURE(cond) \
+ ((void) ((cond) || \
+ ((isc_assertion_failed)(__FILE__, __LINE__, \
+ isc_assertiontype_ensure, \
+ #cond), 0)))
+#else
+#define ISC_ENSURE(cond) ((void) 0)
+#endif /* ISC_CHECK_ENSURE */
+
+#if ISC_CHECK_INSIST != 0
+#define ISC_INSIST(cond) \
+ ((void) ((cond) || \
+ ((isc_assertion_failed)(__FILE__, __LINE__, \
+ isc_assertiontype_insist, \
+ #cond), 0)))
+#else
+#define ISC_INSIST(cond) ((void) 0)
+#endif /* ISC_CHECK_INSIST */
+
+#if ISC_CHECK_INVARIANT != 0
+#define ISC_INVARIANT(cond) \
+ ((void) ((cond) || \
+ ((isc_assertion_failed)(__FILE__, __LINE__, \
+ isc_assertiontype_invariant, \
+ #cond), 0)))
+#else
+#define ISC_INVARIANT(cond) ((void) 0)
+#endif /* ISC_CHECK_INVARIANT */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ASSERTIONS_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/backtrace.h b/contrib/ntp/libntp/lib/isc/include/isc/backtrace.h
new file mode 100644
index 000000000000..7d7fc3217212
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/backtrace.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: backtrace.h,v 1.2 2009/09/01 18:40:25 jinmei Exp $ */
+
+/*! \file isc/backtrace.h
+ * \brief provide a back trace of the running process to help debug problems.
+ *
+ * This module tries to get a back trace of the process using some platform
+ * dependent way when available. It also manages an internal symbol table
+ * that maps function addresses used in the process to their textual symbols.
+ * This module is expected to be used to help debug when some fatal error
+ * happens.
+ *
+ * IMPORTANT NOTE: since the (major) intended use case of this module is
+ * dumping a back trace on a fatal error, normally followed by self termination,
+ * functions defined in this module generally doesn't employ assertion checks
+ * (if it did, a program bug could cause infinite recursive calls to a
+ * backtrace function). These functions still perform minimal checks and return
+ * ISC_R_FAILURE if they detect an error, but the caller should therefore be
+ * very careful about the use of these functions, and generally discouraged to
+ * use them except in an exit path. The exception is
+ * isc_backtrace_getsymbolfromindex(), which is expected to be used in a
+ * non-error-handling context and validates arguments with assertion checks.
+ */
+
+#ifndef ISC_BACKTRACE_H
+#define ISC_BACKTRACE_H 1
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/types.h>
+
+/***
+ *** Types
+ ***/
+struct isc_backtrace_symmap {
+ void *addr;
+ const char *symbol;
+};
+
+extern const int isc__backtrace_nsymbols;
+extern const isc_backtrace_symmap_t isc__backtrace_symtable[];
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+isc_result_t
+isc_backtrace_gettrace(void **addrs, int maxaddrs, int *nframes);
+/*%<
+ * Get a back trace of the running process above this function itself. On
+ * success, addrs[i] will store the address of the call point of the i-th
+ * stack frame (addrs[0] is the caller of this function). *nframes will store
+ * the total number of frames.
+ *
+ * Requires (note that these are not ensured by assertion checks, see above):
+ *
+ *\li 'addrs' is a valid array containing at least 'maxaddrs' void * entries.
+ *
+ *\li 'nframes' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_FAILURE
+ *\li #ISC_R_NOTFOUND
+ *\li #ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_backtrace_getsymbolfromindex(int idx, const void **addrp,
+ const char **symbolp);
+/*%<
+ * Returns the content of the internal symbol table of the given index.
+ * On success, *addrsp and *symbolp point to the address and the symbol of
+ * the 'index'th entry of the table, respectively. If 'idx' is not in the
+ * range of the symbol table, ISC_R_RANGE will be returned.
+ *
+ * Requires
+ *
+ *\li 'addrp' must be non NULL && '*addrp' == NULL.
+ *
+ *\li 'symbolp' must be non NULL && '*symbolp' == NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_RANGE
+ */
+
+isc_result_t
+isc_backtrace_getsymbol(const void *addr, const char **symbolp,
+ unsigned long *offsetp);
+/*%<
+ * Searches the internal symbol table for the symbol that most matches the
+ * given 'addr'. On success, '*symbolp' will point to the name of function
+ * to which the address 'addr' belong, and '*offsetp' will store the offset
+ * from the function's entry address to 'addr'.
+ *
+ * Requires (note that these are not ensured by assertion checks, see above):
+ *
+ *\li 'symbolp' must be non NULL && '*symbolp' == NULL.
+ *
+ *\li 'offsetp' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_FAILURE
+ *\li #ISC_R_NOTFOUND
+ */
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BACKTRACE_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/bind9.h b/contrib/ntp/libntp/lib/isc/include/isc/bind9.h
new file mode 100644
index 000000000000..00bcb24c4a9b
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/bind9.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2009 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: bind9.h,v 1.2 2009/12/05 23:31:41 each Exp $ */
+
+#ifndef ISC_BIND9_H
+#define ISC_BIND9_H 1
+
+/*
+ * This determines whether we are building BIND9 or using the exported
+ * libisc/libdns libraries. The version of this file included in the
+ * standard BIND9 build defines BIND9; the version included with the
+ * exportable libraries does not.
+ */
+#define BIND9 1
+
+#endif /* ISC_BIND9_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/boolean.h b/contrib/ntp/libntp/lib/isc/include/isc/boolean.h
new file mode 100644
index 000000000000..348b096912aa
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/boolean.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: boolean.h,v 1.19 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_BOOLEAN_H
+#define ISC_BOOLEAN_H 1
+
+/*! \file isc/boolean.h */
+
+typedef enum { isc_boolean_false = 0, isc_boolean_true = 1 } isc_boolean_t;
+
+#define ISC_FALSE isc_boolean_false
+#define ISC_TRUE isc_boolean_true
+#define ISC_TF(x) ((x) ? ISC_TRUE : ISC_FALSE)
+
+#endif /* ISC_BOOLEAN_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/buffer.h b/contrib/ntp/libntp/lib/isc/include/isc/buffer.h
new file mode 100644
index 000000000000..ae7e4c3dfc34
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/buffer.h
@@ -0,0 +1,904 @@
+/*
+ * Copyright (C) 2004-2008, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: buffer.h,v 1.55 2010/12/20 23:47:21 tbox Exp $ */
+
+#ifndef ISC_BUFFER_H
+#define ISC_BUFFER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/buffer.h
+ *
+ * \brief A buffer is a region of memory, together with a set of related subregions.
+ * Buffers are used for parsing and I/O operations.
+ *
+ * The 'used region' and the 'available' region are disjoint, and their
+ * union is the buffer's region. The used region extends from the beginning
+ * of the buffer region to the last used byte. The available region
+ * extends from one byte greater than the last used byte to the end of the
+ * buffer's region. The size of the used region can be changed using various
+ * buffer commands. Initially, the used region is empty.
+ *
+ * The used region is further subdivided into two disjoint regions: the
+ * 'consumed region' and the 'remaining region'. The union of these two
+ * regions is the used region. The consumed region extends from the beginning
+ * of the used region to the byte before the 'current' offset (if any). The
+ * 'remaining' region the current pointer to the end of the used
+ * region. The size of the consumed region can be changed using various
+ * buffer commands. Initially, the consumed region is empty.
+ *
+ * The 'active region' is an (optional) subregion of the remaining region.
+ * It extends from the current offset to an offset in the remaining region
+ * that is selected with isc_buffer_setactive(). Initially, the active region
+ * is empty. If the current offset advances beyond the chosen offset, the
+ * active region will also be empty.
+ *
+ * \verbatim
+ * /------------entire length---------------\
+ * /----- used region -----\/-- available --\
+ * +----------------------------------------+
+ * | consumed | remaining | |
+ * +----------------------------------------+
+ * a b c d e
+ *
+ * a == base of buffer.
+ * b == current pointer. Can be anywhere between a and d.
+ * c == active pointer. Meaningful between b and d.
+ * d == used pointer.
+ * e == length of buffer.
+ *
+ * a-e == entire length of buffer.
+ * a-d == used region.
+ * a-b == consumed region.
+ * b-d == remaining region.
+ * b-c == optional active region.
+ *\endverbatim
+ *
+ * The following invariants are maintained by all routines:
+ *
+ *\code
+ * length > 0
+ *
+ * base is a valid pointer to length bytes of memory
+ *
+ * 0 <= used <= length
+ *
+ * 0 <= current <= used
+ *
+ * 0 <= active <= used
+ * (although active < current implies empty active region)
+ *\endcode
+ *
+ * \li MP:
+ * Buffers have no synchronization. Clients must ensure exclusive
+ * access.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * Memory: 1 pointer + 6 unsigned integers per buffer.
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/magic.h>
+#include <isc/types.h>
+
+/*!
+ * To make many functions be inline macros (via \#define) define this.
+ * If it is undefined, a function will be used.
+ */
+/* #define ISC_BUFFER_USEINLINE */
+
+ISC_LANG_BEGINDECLS
+
+/*@{*/
+/*!
+ *** Magic numbers
+ ***/
+#define ISC_BUFFER_MAGIC 0x42756621U /* Buf!. */
+#define ISC_BUFFER_VALID(b) ISC_MAGIC_VALID(b, ISC_BUFFER_MAGIC)
+/*@}*/
+
+/*
+ * The following macros MUST be used only on valid buffers. It is the
+ * caller's responsibility to ensure this by using the ISC_BUFFER_VALID
+ * check above, or by calling another isc_buffer_*() function (rather than
+ * another macro.)
+ */
+
+/*@{*/
+/*!
+ * Fundamental buffer elements. (A through E in the introductory comment.)
+ */
+#define isc_buffer_base(b) ((void *)(b)->base) /*a*/
+#define isc_buffer_current(b) \
+ ((void *)((unsigned char *)(b)->base + (b)->current)) /*b*/
+#define isc_buffer_active(b) \
+ ((void *)((unsigned char *)(b)->base + (b)->active)) /*c*/
+#define isc_buffer_used(b) \
+ ((void *)((unsigned char *)(b)->base + (b)->used)) /*d*/
+#define isc_buffer_length(b) ((b)->length) /*e*/
+/*@}*/
+
+/*@{*/
+/*!
+ * Derived lengths. (Described in the introductory comment.)
+ */
+#define isc_buffer_usedlength(b) ((b)->used) /* d-a */
+#define isc_buffer_consumedlength(b) ((b)->current) /* b-a */
+#define isc_buffer_remaininglength(b) ((b)->used - (b)->current) /* d-b */
+#define isc_buffer_activelength(b) ((b)->active - (b)->current) /* c-b */
+#define isc_buffer_availablelength(b) ((b)->length - (b)->used) /* e-d */
+/*@}*/
+
+/*!
+ * Note that the buffer structure is public. This is principally so buffer
+ * operations can be implemented using macros. Applications are strongly
+ * discouraged from directly manipulating the structure.
+ */
+
+struct isc_buffer {
+ unsigned int magic;
+ void *base;
+ /*@{*/
+ /*! The following integers are byte offsets from 'base'. */
+ unsigned int length;
+ unsigned int used;
+ unsigned int current;
+ unsigned int active;
+ /*@}*/
+ /*! linkable */
+ ISC_LINK(isc_buffer_t) link;
+ /*! private internal elements */
+ isc_mem_t *mctx;
+};
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_buffer_allocate(isc_mem_t *mctx, isc_buffer_t **dynbuffer,
+ unsigned int length);
+/*!<
+ * \brief Allocate a dynamic linkable buffer which has "length" bytes in the
+ * data region.
+ *
+ * Requires:
+ *\li "mctx" is valid.
+ *
+ *\li "dynbuffer" is non-NULL, and "*dynbuffer" is NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS - success
+ *\li ISC_R_NOMEMORY - no memory available
+ *
+ * Note:
+ *\li Changing the buffer's length field is not permitted.
+ */
+
+void
+isc_buffer_free(isc_buffer_t **dynbuffer);
+/*!<
+ * \brief Release resources allocated for a dynamic buffer.
+ *
+ * Requires:
+ *\li "dynbuffer" is not NULL.
+ *
+ *\li "*dynbuffer" is a valid dynamic buffer.
+ *
+ * Ensures:
+ *\li "*dynbuffer" will be NULL on return, and all memory associated with
+ * the dynamic buffer is returned to the memory context used in
+ * isc_buffer_allocate().
+ */
+
+void
+isc__buffer_init(isc_buffer_t *b, const void *base, unsigned int length);
+/*!<
+ * \brief Make 'b' refer to the 'length'-byte region starting at base.
+ *
+ * Requires:
+ *
+ *\li 'length' > 0
+ *
+ *\li 'base' is a pointer to a sequence of 'length' bytes.
+ *
+ */
+
+void
+isc__buffer_initnull(isc_buffer_t *b);
+/*!<
+ *\brief Initialize a buffer 'b' with a null data and zero length/
+ */
+
+void
+isc_buffer_reinit(isc_buffer_t *b, void *base, unsigned int length);
+/*!<
+ * \brief Make 'b' refer to the 'length'-byte region starting at base.
+ * Any existing data will be copied.
+ *
+ * Requires:
+ *
+ *\li 'length' > 0 AND length >= previous length
+ *
+ *\li 'base' is a pointer to a sequence of 'length' bytes.
+ *
+ */
+
+void
+isc__buffer_invalidate(isc_buffer_t *b);
+/*!<
+ * \brief Make 'b' an invalid buffer.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ * Ensures:
+ *\li If assertion checking is enabled, future attempts to use 'b' without
+ * calling isc_buffer_init() on it will cause an assertion failure.
+ */
+
+void
+isc__buffer_region(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_usedregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the used region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_availableregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the available region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_add(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Increase the 'used' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ *\li used + n <= length
+ *
+ */
+
+void
+isc__buffer_subtract(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Decrease the 'used' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ *\li used >= n
+ *
+ */
+
+void
+isc__buffer_clear(isc_buffer_t *b);
+/*!<
+ * \brief Make the used region empty.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ *\li used = 0
+ *
+ */
+
+void
+isc__buffer_consumedregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the consumed region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_remainingregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the remaining region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_activeregion(isc_buffer_t *b, isc_region_t *r);
+/*!<
+ * \brief Make 'r' refer to the active region of 'b'.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' points to a region structure.
+ */
+
+void
+isc__buffer_setactive(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Sets the end of the active region 'n' bytes after current.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li current + n <= used
+ */
+
+void
+isc__buffer_first(isc_buffer_t *b);
+/*!<
+ * \brief Make the consumed region empty.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ *\li current == 0
+ *
+ */
+
+void
+isc__buffer_forward(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Increase the 'consumed' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ *\li current + n <= used
+ *
+ */
+
+void
+isc__buffer_back(isc_buffer_t *b, unsigned int n);
+/*!<
+ * \brief Decrease the 'consumed' region of 'b' by 'n' bytes.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ *\li n <= current
+ *
+ */
+
+void
+isc_buffer_compact(isc_buffer_t *b);
+/*!<
+ * \brief Compact the used region by moving the remaining region so it occurs
+ * at the start of the buffer. The used region is shrunk by the size of
+ * the consumed region, and the consumed region is then made empty.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer
+ *
+ * Ensures:
+ *
+ *\li current == 0
+ *
+ *\li The size of the used region is now equal to the size of the remaining
+ * region (as it was before the call). The contents of the used region
+ * are those of the remaining region (as it was before the call).
+ */
+
+isc_uint8_t
+isc_buffer_getuint8(isc_buffer_t *b);
+/*!<
+ * \brief Read an unsigned 8-bit integer from 'b' and return it.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the available region of 'b' is at least 1.
+ *
+ * Ensures:
+ *
+ *\li The current pointer in 'b' is advanced by 1.
+ *
+ * Returns:
+ *
+ *\li A 8-bit unsigned integer.
+ */
+
+void
+isc__buffer_putuint8(isc_buffer_t *b, isc_uint8_t val);
+/*!<
+ * \brief Store an unsigned 8-bit integer from 'val' into 'b'.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the unused region of 'b' is at least 1.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 1.
+ */
+
+isc_uint16_t
+isc_buffer_getuint16(isc_buffer_t *b);
+/*!<
+ * \brief Read an unsigned 16-bit integer in network byte order from 'b', convert
+ * it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the available region of 'b' is at least 2.
+ *
+ * Ensures:
+ *
+ *\li The current pointer in 'b' is advanced by 2.
+ *
+ * Returns:
+ *
+ *\li A 16-bit unsigned integer.
+ */
+
+void
+isc__buffer_putuint16(isc_buffer_t *b, isc_uint16_t val);
+/*!<
+ * \brief Store an unsigned 16-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the unused region of 'b' is at least 2.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 2.
+ */
+
+isc_uint32_t
+isc_buffer_getuint32(isc_buffer_t *b);
+/*!<
+ * \brief Read an unsigned 32-bit integer in network byte order from 'b', convert
+ * it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the available region of 'b' is at least 4.
+ *
+ * Ensures:
+ *
+ *\li The current pointer in 'b' is advanced by 4.
+ *
+ * Returns:
+ *
+ *\li A 32-bit unsigned integer.
+ */
+
+void
+isc__buffer_putuint32(isc_buffer_t *b, isc_uint32_t val);
+/*!<
+ * \brief Store an unsigned 32-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the unused region of 'b' is at least 4.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 4.
+ */
+
+isc_uint64_t
+isc_buffer_getuint48(isc_buffer_t *b);
+/*!<
+ * \brief Read an unsigned 48-bit integer in network byte order from 'b',
+ * convert it to host byte order, and return it.
+ *
+ * Requires:
+ *
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the available region of 'b' is at least 6.
+ *
+ * Ensures:
+ *
+ *\li The current pointer in 'b' is advanced by 6.
+ *
+ * Returns:
+ *
+ *\li A 48-bit unsigned integer (stored in a 64-bit integer).
+ */
+
+void
+isc__buffer_putuint48(isc_buffer_t *b, isc_uint64_t val);
+/*!<
+ * \brief Store an unsigned 48-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li The length of the unused region of 'b' is at least 6.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 6.
+ */
+
+void
+isc__buffer_putuint24(isc_buffer_t *b, isc_uint32_t val);
+/*!<
+ * Store an unsigned 24-bit integer in host byte order from 'val'
+ * into 'b' in network byte order.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ * The length of the unused region of 'b' is at least 3.
+ *
+ * Ensures:
+ *\li The used pointer in 'b' is advanced by 3.
+ */
+
+void
+isc__buffer_putmem(isc_buffer_t *b, const unsigned char *base,
+ unsigned int length);
+/*!<
+ * \brief Copy 'length' bytes of memory at 'base' into 'b'.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'base' points to 'length' bytes of valid memory.
+ *
+ */
+
+void
+isc__buffer_putstr(isc_buffer_t *b, const char *source);
+/*!<
+ * \brief Copy 'source' into 'b', not including terminating NUL.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'source' to be a valid NULL terminated string.
+ *
+ *\li strlen(source) <= isc_buffer_available(b)
+ */
+
+isc_result_t
+isc_buffer_copyregion(isc_buffer_t *b, const isc_region_t *r);
+/*!<
+ * \brief Copy the contents of 'r' into 'b'.
+ *
+ * Requires:
+ *\li 'b' is a valid buffer.
+ *
+ *\li 'r' is a valid region.
+ *
+ * Returns:
+ *
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_NOSPACE The available region of 'b' is not
+ * big enough.
+ */
+
+ISC_LANG_ENDDECLS
+
+/*
+ * Inline macro versions of the functions. These should never be called
+ * directly by an application, but will be used by the functions within
+ * buffer.c. The callers should always use "isc_buffer_*()" names, never
+ * ones beginning with "isc__"
+ */
+
+/*! \note
+ * XXXDCL Something more could be done with initializing buffers that
+ * point to const data. For example, a new function, isc_buffer_initconst,
+ * could be used, and a new boolean flag in the buffer structure could
+ * indicate whether the buffer was initialized with that function.
+ * (isc_bufer_init itself would be reprototyped to *not* have its "base"
+ * parameter be const.) Then if the boolean were true, the isc_buffer_put*
+ * functions could assert a contractual requirement for a non-const buffer.
+ * One drawback is that the isc_buffer_* functions (macros) that return
+ * pointers would still need to return non-const pointers to avoid compiler
+ * warnings, so it would be up to code that uses them to have to deal
+ * with the possibility that the buffer was initialized as const --
+ * a problem that they *already* have to deal with but have absolutely
+ * no ability to. With a new isc_buffer_isconst() function returning
+ * true/false, they could at least assert a contractual requirement for
+ * non-const buffers when needed.
+ */
+#define ISC__BUFFER_INIT(_b, _base, _length) \
+ do { \
+ union { \
+ const void * konst; \
+ void * var; \
+ } _u; \
+ _u.konst = (_base); \
+ (_b)->base = _u.var; \
+ (_b)->length = (_length); \
+ (_b)->used = 0; \
+ (_b)->current = 0; \
+ (_b)->active = 0; \
+ (_b)->mctx = NULL; \
+ ISC_LINK_INIT(_b, link); \
+ (_b)->magic = ISC_BUFFER_MAGIC; \
+ } while (0)
+
+#define ISC__BUFFER_INITNULL(_b) ISC__BUFFER_INIT(_b, NULL, 0)
+
+#define ISC__BUFFER_INVALIDATE(_b) \
+ do { \
+ (_b)->magic = 0; \
+ (_b)->base = NULL; \
+ (_b)->length = 0; \
+ (_b)->used = 0; \
+ (_b)->current = 0; \
+ (_b)->active = 0; \
+ } while (0)
+
+#define ISC__BUFFER_REGION(_b, _r) \
+ do { \
+ (_r)->base = (_b)->base; \
+ (_r)->length = (_b)->length; \
+ } while (0)
+
+#define ISC__BUFFER_USEDREGION(_b, _r) \
+ do { \
+ (_r)->base = (_b)->base; \
+ (_r)->length = (_b)->used; \
+ } while (0)
+
+#define ISC__BUFFER_AVAILABLEREGION(_b, _r) \
+ do { \
+ (_r)->base = isc_buffer_used(_b); \
+ (_r)->length = isc_buffer_availablelength(_b); \
+ } while (0)
+
+#define ISC__BUFFER_ADD(_b, _n) \
+ do { \
+ (_b)->used += (_n); \
+ } while (0)
+
+#define ISC__BUFFER_SUBTRACT(_b, _n) \
+ do { \
+ (_b)->used -= (_n); \
+ if ((_b)->current > (_b)->used) \
+ (_b)->current = (_b)->used; \
+ if ((_b)->active > (_b)->used) \
+ (_b)->active = (_b)->used; \
+ } while (0)
+
+#define ISC__BUFFER_CLEAR(_b) \
+ do { \
+ (_b)->used = 0; \
+ (_b)->current = 0; \
+ (_b)->active = 0; \
+ } while (0)
+
+#define ISC__BUFFER_CONSUMEDREGION(_b, _r) \
+ do { \
+ (_r)->base = (_b)->base; \
+ (_r)->length = (_b)->current; \
+ } while (0)
+
+#define ISC__BUFFER_REMAININGREGION(_b, _r) \
+ do { \
+ (_r)->base = isc_buffer_current(_b); \
+ (_r)->length = isc_buffer_remaininglength(_b); \
+ } while (0)
+
+#define ISC__BUFFER_ACTIVEREGION(_b, _r) \
+ do { \
+ if ((_b)->current < (_b)->active) { \
+ (_r)->base = isc_buffer_current(_b); \
+ (_r)->length = isc_buffer_activelength(_b); \
+ } else { \
+ (_r)->base = NULL; \
+ (_r)->length = 0; \
+ } \
+ } while (0)
+
+#define ISC__BUFFER_SETACTIVE(_b, _n) \
+ do { \
+ (_b)->active = (_b)->current + (_n); \
+ } while (0)
+
+#define ISC__BUFFER_FIRST(_b) \
+ do { \
+ (_b)->current = 0; \
+ } while (0)
+
+#define ISC__BUFFER_FORWARD(_b, _n) \
+ do { \
+ (_b)->current += (_n); \
+ } while (0)
+
+#define ISC__BUFFER_BACK(_b, _n) \
+ do { \
+ (_b)->current -= (_n); \
+ } while (0)
+
+#define ISC__BUFFER_PUTMEM(_b, _base, _length) \
+ do { \
+ memcpy(isc_buffer_used(_b), (_base), (_length)); \
+ (_b)->used += (_length); \
+ } while (0)
+
+#define ISC__BUFFER_PUTSTR(_b, _source) \
+ do { \
+ unsigned int _length; \
+ unsigned char *_cp; \
+ _length = strlen(_source); \
+ _cp = isc_buffer_used(_b); \
+ memcpy(_cp, (_source), _length); \
+ (_b)->used += (_length); \
+ } while (0)
+
+#define ISC__BUFFER_PUTUINT8(_b, _val) \
+ do { \
+ unsigned char *_cp; \
+ isc_uint8_t _val2 = (_val); \
+ _cp = isc_buffer_used(_b); \
+ (_b)->used++; \
+ _cp[0] = _val2 & 0x00ff; \
+ } while (0)
+
+#define ISC__BUFFER_PUTUINT16(_b, _val) \
+ do { \
+ unsigned char *_cp; \
+ isc_uint16_t _val2 = (_val); \
+ _cp = isc_buffer_used(_b); \
+ (_b)->used += 2; \
+ _cp[0] = (unsigned char)((_val2 & 0xff00U) >> 8); \
+ _cp[1] = (unsigned char)(_val2 & 0x00ffU); \
+ } while (0)
+
+#define ISC__BUFFER_PUTUINT24(_b, _val) \
+ do { \
+ unsigned char *_cp; \
+ isc_uint32_t _val2 = (_val); \
+ _cp = isc_buffer_used(_b); \
+ (_b)->used += 3; \
+ _cp[0] = (unsigned char)((_val2 & 0xff0000U) >> 16); \
+ _cp[1] = (unsigned char)((_val2 & 0xff00U) >> 8); \
+ _cp[2] = (unsigned char)(_val2 & 0x00ffU); \
+ } while (0)
+
+#define ISC__BUFFER_PUTUINT32(_b, _val) \
+ do { \
+ unsigned char *_cp; \
+ isc_uint32_t _val2 = (_val); \
+ _cp = isc_buffer_used(_b); \
+ (_b)->used += 4; \
+ _cp[0] = (unsigned char)((_val2 & 0xff000000) >> 24); \
+ _cp[1] = (unsigned char)((_val2 & 0x00ff0000) >> 16); \
+ _cp[2] = (unsigned char)((_val2 & 0x0000ff00) >> 8); \
+ _cp[3] = (unsigned char)((_val2 & 0x000000ff)); \
+ } while (0)
+
+#if defined(ISC_BUFFER_USEINLINE)
+#define isc_buffer_init ISC__BUFFER_INIT
+#define isc_buffer_initnull ISC__BUFFER_INITNULL
+#define isc_buffer_invalidate ISC__BUFFER_INVALIDATE
+#define isc_buffer_region ISC__BUFFER_REGION
+#define isc_buffer_usedregion ISC__BUFFER_USEDREGION
+#define isc_buffer_availableregion ISC__BUFFER_AVAILABLEREGION
+#define isc_buffer_add ISC__BUFFER_ADD
+#define isc_buffer_subtract ISC__BUFFER_SUBTRACT
+#define isc_buffer_clear ISC__BUFFER_CLEAR
+#define isc_buffer_consumedregion ISC__BUFFER_CONSUMEDREGION
+#define isc_buffer_remainingregion ISC__BUFFER_REMAININGREGION
+#define isc_buffer_activeregion ISC__BUFFER_ACTIVEREGION
+#define isc_buffer_setactive ISC__BUFFER_SETACTIVE
+#define isc_buffer_first ISC__BUFFER_FIRST
+#define isc_buffer_forward ISC__BUFFER_FORWARD
+#define isc_buffer_back ISC__BUFFER_BACK
+#define isc_buffer_putmem ISC__BUFFER_PUTMEM
+#define isc_buffer_putstr ISC__BUFFER_PUTSTR
+#define isc_buffer_putuint8 ISC__BUFFER_PUTUINT8
+#define isc_buffer_putuint16 ISC__BUFFER_PUTUINT16
+#define isc_buffer_putuint24 ISC__BUFFER_PUTUINT24
+#define isc_buffer_putuint32 ISC__BUFFER_PUTUINT32
+#else
+#define isc_buffer_init isc__buffer_init
+#define isc_buffer_initnull isc__buffer_initnull
+#define isc_buffer_invalidate isc__buffer_invalidate
+#define isc_buffer_region isc__buffer_region
+#define isc_buffer_usedregion isc__buffer_usedregion
+#define isc_buffer_availableregion isc__buffer_availableregion
+#define isc_buffer_add isc__buffer_add
+#define isc_buffer_subtract isc__buffer_subtract
+#define isc_buffer_clear isc__buffer_clear
+#define isc_buffer_consumedregion isc__buffer_consumedregion
+#define isc_buffer_remainingregion isc__buffer_remainingregion
+#define isc_buffer_activeregion isc__buffer_activeregion
+#define isc_buffer_setactive isc__buffer_setactive
+#define isc_buffer_first isc__buffer_first
+#define isc_buffer_forward isc__buffer_forward
+#define isc_buffer_back isc__buffer_back
+#define isc_buffer_putmem isc__buffer_putmem
+#define isc_buffer_putstr isc__buffer_putstr
+#define isc_buffer_putuint8 isc__buffer_putuint8
+#define isc_buffer_putuint16 isc__buffer_putuint16
+#define isc_buffer_putuint24 isc__buffer_putuint24
+#define isc_buffer_putuint32 isc__buffer_putuint32
+#endif
+
+/*
+ * No inline method for this one (yet).
+ */
+#define isc_buffer_putuint48 isc__buffer_putuint48
+
+#endif /* ISC_BUFFER_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/error.h b/contrib/ntp/libntp/lib/isc/include/isc/error.h
new file mode 100644
index 000000000000..e0cdfa83e7cb
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/error.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: error.h,v 1.22 2009/09/29 23:48:04 tbox Exp $ */
+
+#ifndef ISC_ERROR_H
+#define ISC_ERROR_H 1
+
+/*! \file isc/error.h */
+
+#include <stdarg.h>
+
+#include <isc/formatcheck.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+ISC_LANG_BEGINDECLS
+
+typedef void (*isc_errorcallback_t)(const char *, int, const char *, va_list);
+
+/*% set unexpected error */
+void
+isc_error_setunexpected(isc_errorcallback_t);
+
+/*% set fatal error */
+void
+isc_error_setfatal(isc_errorcallback_t);
+
+/*% unexpected error */
+void
+isc_error_unexpected(const char *, int, const char *, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+
+/*% fatal error */
+ISC_PLATFORM_NORETURN_PRE void
+isc_error_fatal(const char *, int, const char *, ...)
+ISC_FORMAT_PRINTF(3, 4) ISC_PLATFORM_NORETURN_POST;
+
+/*% runtimecheck error */
+void
+isc_error_runtimecheck(const char *, int, const char *);
+
+#define ISC_ERROR_RUNTIMECHECK(cond) \
+ ((void) ((cond) || \
+ ((isc_error_runtimecheck)(__FILE__, __LINE__, #cond), 0)))
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ERROR_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/event.h b/contrib/ntp/libntp/lib/isc/include/isc/event.h
new file mode 100644
index 000000000000..68fabb2fcc3c
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/event.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: event.h,v 1.34 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_EVENT_H
+#define ISC_EVENT_H 1
+
+/*! \file isc/event.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*****
+ ***** Events.
+ *****/
+
+typedef void (*isc_eventdestructor_t)(isc_event_t *);
+
+#define ISC_EVENT_COMMON(ltype) \
+ size_t ev_size; \
+ unsigned int ev_attributes; \
+ void * ev_tag; \
+ isc_eventtype_t ev_type; \
+ isc_taskaction_t ev_action; \
+ void * ev_arg; \
+ void * ev_sender; \
+ isc_eventdestructor_t ev_destroy; \
+ void * ev_destroy_arg; \
+ ISC_LINK(ltype) ev_link
+
+/*%
+ * Attributes matching a mask of 0x000000ff are reserved for the task library's
+ * definition. Attributes of 0xffffff00 may be used by the application
+ * or non-ISC libraries.
+ */
+#define ISC_EVENTATTR_NOPURGE 0x00000001
+
+/*%
+ * The ISC_EVENTATTR_CANCELED attribute is intended to indicate
+ * that an event is delivered as a result of a canceled operation
+ * rather than successful completion, by mutual agreement
+ * between the sender and receiver. It is not set or used by
+ * the task system.
+ */
+#define ISC_EVENTATTR_CANCELED 0x00000002
+
+#define ISC_EVENT_INIT(event, sz, at, ta, ty, ac, ar, sn, df, da) \
+do { \
+ (event)->ev_size = (sz); \
+ (event)->ev_attributes = (at); \
+ (event)->ev_tag = (ta); \
+ (event)->ev_type = (ty); \
+ (event)->ev_action = (ac); \
+ (event)->ev_arg = (ar); \
+ (event)->ev_sender = (sn); \
+ (event)->ev_destroy = (df); \
+ (event)->ev_destroy_arg = (da); \
+ ISC_LINK_INIT((event), ev_link); \
+} while (0)
+
+/*%
+ * This structure is public because "subclassing" it may be useful when
+ * defining new event types.
+ */
+struct isc_event {
+ ISC_EVENT_COMMON(struct isc_event);
+};
+
+#define ISC_EVENTTYPE_FIRSTEVENT 0x00000000
+#define ISC_EVENTTYPE_LASTEVENT 0xffffffff
+
+#define ISC_EVENT_PTR(p) ((isc_event_t **)(void *)(p))
+
+ISC_LANG_BEGINDECLS
+
+isc_event_t *
+isc_event_allocate(isc_mem_t *mctx, void *sender, isc_eventtype_t type,
+ isc_taskaction_t action, const void *arg, size_t size);
+/*%<
+ * Allocate an event structure.
+ *
+ * Allocate and initialize in a structure with initial elements
+ * defined by:
+ *
+ * \code
+ * struct {
+ * ISC_EVENT_COMMON(struct isc_event);
+ * ...
+ * };
+ * \endcode
+ *
+ * Requires:
+ *\li 'size' >= sizeof(struct isc_event)
+ *\li 'action' to be non NULL
+ *
+ * Returns:
+ *\li a pointer to a initialized structure of the requested size.
+ *\li NULL if unable to allocate memory.
+ */
+
+void
+isc_event_free(isc_event_t **);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_EVENT_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/eventclass.h b/contrib/ntp/libntp/lib/isc/include/isc/eventclass.h
new file mode 100644
index 000000000000..9e6c145ac732
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/eventclass.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: eventclass.h,v 1.18 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_EVENTCLASS_H
+#define ISC_EVENTCLASS_H 1
+
+/*! \file isc/eventclass.h
+ ***** Registry of Predefined Event Type Classes
+ *****/
+
+/*%
+ * An event class is an unsigned 16 bit number. Each class may contain up
+ * to 65536 events. An event type is formed by adding the event number
+ * within the class to the class number.
+ *
+ */
+
+#define ISC_EVENTCLASS(eclass) ((eclass) << 16)
+
+/*@{*/
+/*!
+ * Classes < 1024 are reserved for ISC use.
+ * Event classes >= 1024 and <= 65535 are reserved for application use.
+ */
+
+#define ISC_EVENTCLASS_TASK ISC_EVENTCLASS(0)
+#define ISC_EVENTCLASS_TIMER ISC_EVENTCLASS(1)
+#define ISC_EVENTCLASS_SOCKET ISC_EVENTCLASS(2)
+#define ISC_EVENTCLASS_FILE ISC_EVENTCLASS(3)
+#define ISC_EVENTCLASS_DNS ISC_EVENTCLASS(4)
+#define ISC_EVENTCLASS_APP ISC_EVENTCLASS(5)
+#define ISC_EVENTCLASS_OMAPI ISC_EVENTCLASS(6)
+#define ISC_EVENTCLASS_RATELIMITER ISC_EVENTCLASS(7)
+#define ISC_EVENTCLASS_ISCCC ISC_EVENTCLASS(8)
+/*@}*/
+
+#endif /* ISC_EVENTCLASS_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/file.h b/contrib/ntp/libntp/lib/isc/include/isc/file.h
new file mode 100644
index 000000000000..5db506a389a4
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/file.h
@@ -0,0 +1,304 @@
+/*
+ * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_FILE_H
+#define ISC_FILE_H 1
+
+/*! \file isc/file.h */
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_file_settime(const char *file, isc_time_t *itime);
+
+isc_result_t
+isc_file_getmodtime(const char *file, isc_time_t *itime);
+/*!<
+ * \brief Get the time of last modification of a file.
+ *
+ * Notes:
+ *\li The time that is set is relative to the (OS-specific) epoch, as are
+ * all isc_time_t structures.
+ *
+ * Requires:
+ *\li file != NULL.
+ *\li time != NULL.
+ *
+ * Ensures:
+ *\li If the file could not be accessed, 'time' is unchanged.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * Success.
+ *\li #ISC_R_NOTFOUND
+ * No such file exists.
+ *\li #ISC_R_INVALIDFILE
+ * The path specified was not usable by the operating system.
+ *\li #ISC_R_NOPERM
+ * The file's metainformation could not be retrieved because
+ * permission was denied to some part of the file's path.
+ *\li #ISC_R_EIO
+ * Hardware error interacting with the filesystem.
+ *\li #ISC_R_UNEXPECTED
+ * Something totally unexpected happened.
+ *
+ */
+
+isc_result_t
+isc_file_mktemplate(const char *path, char *buf, size_t buflen);
+/*!<
+ * \brief Generate a template string suitable for use with isc_file_openunique().
+ *
+ * Notes:
+ *\li This function is intended to make creating temporary files
+ * portable between different operating systems.
+ *
+ *\li The path is prepended to an implementation-defined string and
+ * placed into buf. The string has no path characters in it,
+ * and its maximum length is 14 characters plus a NUL. Thus
+ * buflen should be at least strlen(path) + 15 characters or
+ * an error will be returned.
+ *
+ * Requires:
+ *\li buf != NULL.
+ *
+ * Ensures:
+ *\li If result == #ISC_R_SUCCESS:
+ * buf contains a string suitable for use as the template argument
+ * to isc_file_openunique().
+ *
+ *\li If result != #ISC_R_SUCCESS:
+ * buf is unchanged.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOSPACE buflen indicates buf is too small for the catenation
+ * of the path with the internal template string.
+ */
+
+
+isc_result_t
+isc_file_openunique(char *templet, FILE **fp);
+isc_result_t
+isc_file_openuniqueprivate(char *templet, FILE **fp);
+isc_result_t
+isc_file_openuniquemode(char *templet, int mode, FILE **fp);
+/*!<
+ * \brief Create and open a file with a unique name based on 'templet'.
+ *
+ * Notes:
+ *\li 'template' is a reserved work in C++. If you want to complain
+ * about the spelling of 'templet', first look it up in the
+ * Merriam-Webster English dictionary. (http://www.m-w.com/)
+ *
+ *\li This function works by using the template to generate file names.
+ * The template must be a writable string, as it is modified in place.
+ * Trailing X characters in the file name (full file name on Unix,
+ * basename on Win32 -- eg, tmp-XXXXXX vs XXXXXX.tmp, respectively)
+ * are replaced with ASCII characters until a non-existent filename
+ * is found. If the template does not include pathname information,
+ * the files in the working directory of the program are searched.
+ *
+ *\li isc_file_mktemplate is a good, portable way to get a template.
+ *
+ * Requires:
+ *\li 'fp' is non-NULL and '*fp' is NULL.
+ *
+ *\li 'template' is non-NULL, and of a form suitable for use by
+ * the system as described above.
+ *
+ * Ensures:
+ *\li If result is #ISC_R_SUCCESS:
+ * *fp points to an stream opening in stdio's "w+" mode.
+ *
+ *\li If result is not #ISC_R_SUCCESS:
+ * *fp is NULL.
+ *
+ * No file is open. Even if one was created (but unable
+ * to be reopened as a stdio FILE pointer) then it has been
+ * removed.
+ *
+ *\li This function does *not* ensure that the template string has not been
+ * modified, even if the operation was unsuccessful.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * Success.
+ *\li #ISC_R_EXISTS
+ * No file with a unique name could be created based on the
+ * template.
+ *\li #ISC_R_INVALIDFILE
+ * The path specified was not usable by the operating system.
+ *\li #ISC_R_NOPERM
+ * The file could not be created because permission was denied
+ * to some part of the file's path.
+ *\li #ISC_R_IOERROR
+ * Hardware error interacting with the filesystem.
+ *\li #ISC_R_UNEXPECTED
+ * Something totally unexpected happened.
+ */
+
+isc_result_t
+isc_file_remove(const char *filename);
+/*!<
+ * \brief Remove the file named by 'filename'.
+ */
+
+isc_result_t
+isc_file_rename(const char *oldname, const char *newname);
+/*!<
+ * \brief Rename the file 'oldname' to 'newname'.
+ */
+
+isc_boolean_t
+isc_file_exists(const char *pathname);
+/*!<
+ * \brief Return #ISC_TRUE if the calling process can tell that the given file exists.
+ * Will not return true if the calling process has insufficient privileges
+ * to search the entire path.
+ */
+
+isc_boolean_t
+isc_file_isabsolute(const char *filename);
+/*!<
+ * \brief Return #ISC_TRUE if the given file name is absolute.
+ */
+
+isc_result_t
+isc_file_isplainfile(const char *name);
+/*!<
+ * \brief Check that the file is a plain file
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * Success. The file is a plain file.
+ *\li #ISC_R_INVALIDFILE
+ * The path specified was not usable by the operating system.
+ *\li #ISC_R_FILENOTFOUND
+ * The file does not exist. This return code comes from
+ * errno=ENOENT when stat returns -1. This code is mentioned
+ * here, because in logconf.c, it is the one rcode that is
+ * permitted in addition to ISC_R_SUCCESS. This is done since
+ * the next call in logconf.c is to isc_stdio_open(), which
+ * will create the file if it can.
+ *\li #other ISC_R_* errors translated from errno
+ * These occur when stat returns -1 and an errno.
+ */
+
+isc_boolean_t
+isc_file_iscurrentdir(const char *filename);
+/*!<
+ * \brief Return #ISC_TRUE if the given file name is the current directory (".").
+ */
+
+isc_boolean_t
+isc_file_ischdiridempotent(const char *filename);
+/*%<
+ * Return #ISC_TRUE if calling chdir(filename) multiple times will give
+ * the same result as calling it once.
+ */
+
+const char *
+isc_file_basename(const char *filename);
+/*%<
+ * Return the final component of the path in the file name.
+ */
+
+isc_result_t
+isc_file_progname(const char *filename, char *buf, size_t buflen);
+/*!<
+ * \brief Given an operating system specific file name "filename"
+ * referring to a program, return the canonical program name.
+ *
+ *
+ * Any directory prefix or executable file name extension (if
+ * used on the OS in case) is stripped. On systems where program
+ * names are case insensitive, the name is canonicalized to all
+ * lower case. The name is written to 'buf', an array of 'buflen'
+ * chars, and null terminated.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOSPACE The name did not fit in 'buf'.
+ */
+
+isc_result_t
+isc_file_template(const char *path, const char *templet, char *buf,
+ size_t buflen);
+/*%<
+ * Create an OS specific template using 'path' to define the directory
+ * 'templet' to describe the filename and store the result in 'buf'
+ * such that path can be renamed to buf atomically.
+ */
+
+isc_result_t
+isc_file_renameunique(const char *file, char *templet);
+/*%<
+ * Rename 'file' using 'templet' as a template for the new file name.
+ */
+
+isc_result_t
+isc_file_absolutepath(const char *filename, char *path, size_t pathlen);
+/*%<
+ * Given a file name, return the fully qualified path to the file.
+ */
+
+/*
+ * XXX We should also have a isc_file_writeeopen() function
+ * for safely open a file in a publicly writable directory
+ * (see write_open() in BIND 8's ns_config.c).
+ */
+
+isc_result_t
+isc_file_truncate(const char *filename, isc_offset_t size);
+/*%<
+ * Truncate/extend the file specified to 'size' bytes.
+ */
+
+isc_result_t
+isc_file_safecreate(const char *filename, FILE **fp);
+/*%<
+ * Open 'filename' for writing, truncating if necessary. Ensure that
+ * if it existed it was a normal file. If creating the file, ensure
+ * that only the owner can read/write it.
+ */
+
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path,
+ char **dirname, char **basename);
+/*%<
+ * Split a path into dirname and basename. If 'path' contains no slash
+ * (or, on windows, backslash), then '*dirname' is set to ".".
+ *
+ * Allocates memory for '*dirname', which can be freed with isc_mem_free().
+ *
+ * Returns:
+ * - ISC_R_SUCCESS on success
+ * - ISC_R_INVALIDFILE if 'path' is empty or ends with '/'
+ * - ISC_R_NOMEMORY if unable to allocate memory
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_FILE_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/formatcheck.h b/contrib/ntp/libntp/lib/isc/include/isc/formatcheck.h
new file mode 100644
index 000000000000..51ce3cac25df
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/formatcheck.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: formatcheck.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_FORMATCHECK_H
+#define ISC_FORMATCHECK_H 1
+
+/*! \file isc/formatcheck.h */
+
+/*%
+ * ISC_FORMAT_PRINTF().
+ *
+ * \li fmt is the location of the format string parameter.
+ * \li args is the location of the first argument (or 0 for no argument checking).
+ *
+ * Note:
+ * \li The first parameter is 1, not 0.
+ */
+#ifdef __GNUC__
+#define ISC_FORMAT_PRINTF(fmt, args) __attribute__((__format__(__printf__, fmt, args)))
+#else
+#define ISC_FORMAT_PRINTF(fmt, args)
+#endif
+
+#endif /* ISC_FORMATCHECK_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/hash.h b/contrib/ntp/libntp/lib/isc/include/isc/hash.h
new file mode 100644
index 000000000000..ca04b4e43c75
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/hash.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: hash.h,v 1.12 2009/01/17 23:47:43 tbox Exp $ */
+
+#ifndef ISC_HASH_H
+#define ISC_HASH_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/hash.h
+ *
+ * \brief The hash API
+ * provides an unpredictable hash value for variable length data.
+ * A hash object contains a random vector (which is hidden from clients
+ * of this API) to make the actual hash value unpredictable.
+ *
+ * The algorithm used in the API guarantees the probability of hash
+ * collision; in the current implementation, as long as the values stored
+ * in the random vector are unpredictable, the probability of hash
+ * collision between arbitrary two different values is at most 1/2^16.
+ *
+ * Although the API is generic about the hash keys, it mainly expects
+ * DNS names (and sometimes IPv4/v6 addresses) as inputs. It has an
+ * upper limit of the input length, and may run slow to calculate the
+ * hash values for large inputs.
+ *
+ * This API is designed to be general so that it can provide multiple
+ * different hash contexts that have different random vectors. However,
+ * it should be typical to have a single context for an entire system.
+ * To support such cases, the API also provides a single-context mode.
+ *
+ * \li MP:
+ * The hash object is almost read-only. Once the internal random vector
+ * is initialized, no write operation will occur, and there will be no
+ * need to lock the object to calculate actual hash values.
+ *
+ * \li Reliability:
+ * In some cases this module uses low-level data copy to initialize the
+ * random vector. Errors in this part are likely to crash the server or
+ * corrupt memory.
+ *
+ * \li Resources:
+ * A buffer, used as a random vector for calculating hash values.
+ *
+ * \li Security:
+ * This module intends to provide unpredictable hash values in
+ * adversarial environments in order to avoid denial of service attacks
+ * to hash buckets.
+ * Its unpredictability relies on the quality of entropy to build the
+ * random vector.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/types.h>
+
+/***
+ *** Functions
+ ***/
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy, unsigned int limit,
+ isc_hash_t **hctx);
+isc_result_t
+isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit);
+/*!<
+ * \brief Create a new hash object.
+ *
+ * isc_hash_ctxcreate() creates a different object.
+ *
+ * isc_hash_create() creates a module-internal object to support the
+ * single-context mode. It should be called only once.
+ *
+ * 'entropy' must be NULL or a valid entropy object. If 'entropy' is NULL,
+ * pseudo random values will be used to build the random vector, which may
+ * weaken security.
+ *
+ * 'limit' specifies the maximum number of hash keys. If it is too large,
+ * these functions may fail.
+ */
+
+void
+isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp);
+/*!<
+ * \brief Attach to a hash object.
+ *
+ * This function is only necessary for the multiple-context mode.
+ */
+
+void
+isc_hash_ctxdetach(isc_hash_t **hctxp);
+/*!<
+ * \brief Detach from a hash object.
+ *
+ * This function is for the multiple-context mode, and takes a valid
+ * hash object as an argument.
+ */
+
+void
+isc_hash_destroy(void);
+/*!<
+ * \brief This function is for the single-context mode, and is expected to be used
+ * as a counterpart of isc_hash_create().
+ *
+ * A valid module-internal hash object must have been created, and this
+ * function should be called only once.
+ */
+
+/*@{*/
+void
+isc_hash_ctxinit(isc_hash_t *hctx);
+void
+isc_hash_init(void);
+/*!<
+ * \brief Initialize a hash object.
+ *
+ * It fills in the random vector with a proper
+ * source of entropy, which is typically from the entropy object specified
+ * at the creation. Thus, it is desirable to call these functions after
+ * initializing the entropy object with some good entropy sources.
+ *
+ * These functions should be called before the first hash calculation.
+ *
+ * isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash
+ * object as an argument.
+ *
+ * isc_hash_init() is for the single-context mode. A valid module-internal
+ * hash object must have been created, and this function should be called only
+ * once.
+ */
+/*@}*/
+
+/*@{*/
+unsigned int
+isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key,
+ unsigned int keylen, isc_boolean_t case_sensitive);
+unsigned int
+isc_hash_calc(const unsigned char *key, unsigned int keylen,
+ isc_boolean_t case_sensitive);
+/*!<
+ * \brief Calculate a hash value.
+ *
+ * isc_hash_ctxinit() is for the multiple-context mode, and takes a valid hash
+ * object as an argument.
+ *
+ * isc_hash_init() is for the single-context mode. A valid module-internal
+ * hash object must have been created.
+ *
+ * 'key' is the hash key, which is a variable length buffer.
+ *
+ * 'keylen' specifies the key length, which must not be larger than the limit
+ * specified for the corresponding hash object.
+ *
+ * 'case_sensitive' specifies whether the hash key should be treated as
+ * case_sensitive values. It should typically be ISC_FALSE if the hash key
+ * is a DNS name.
+ */
+/*@}*/
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HASH_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/interfaceiter.h b/contrib/ntp/libntp/lib/isc/include/isc/interfaceiter.h
new file mode 100644
index 000000000000..544f54b12ad4
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/interfaceiter.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: interfaceiter.h,v 1.17 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_INTERFACEITER_H
+#define ISC_INTERFACEITER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/interfaceiter.h
+ * \brief Iterates over the list of network interfaces.
+ *
+ * Interfaces whose address family is not supported are ignored and never
+ * returned by the iterator. Interfaces whose netmask, interface flags,
+ * or similar cannot be obtained are also ignored, and the failure is logged.
+ *
+ * Standards:
+ * The API for scanning varies greatly among operating systems.
+ * This module attempts to hide the differences.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/netaddr.h>
+#include <isc/types.h>
+
+/*!
+ * \brief Public structure describing a network interface.
+ */
+
+struct isc_interface {
+ char name[32]; /*%< Interface name, null-terminated. */
+ unsigned int af; /*%< Address family. */
+ isc_netaddr_t address; /*%< Local address. */
+ isc_netaddr_t netmask; /*%< Network mask. */
+ isc_netaddr_t broadcast; /*&< Broadcast address. */
+ isc_netaddr_t dstaddress; /*%< Destination address (point-to-point only). */
+ isc_uint32_t flags; /*%< Flags; see INTERFACE flags. */
+ unsigned int ifindex; /*%< Interface index for IP(V6)_MULTICAST_IF. */
+};
+
+/*@{*/
+/*! Interface flags. */
+
+#define INTERFACE_F_UP 0x00000001U
+#define INTERFACE_F_POINTTOPOINT 0x00000002U
+#define INTERFACE_F_LOOPBACK 0x00000004U
+#define INTERFACE_F_BROADCAST 0x00000008U
+#define INTERFACE_F_MULTICAST 0x00000010U
+#define INTERFACE_F_PRIVACY 0x00000020U /* RFC 4941 */
+/*@}*/
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp);
+/*!<
+ * \brief Create an iterator for traversing the operating system's list
+ * of network interfaces.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ * \li #ISC_R_NOMEMORY
+ *\li Various network-related errors
+ */
+
+isc_result_t
+isc_interfaceiter_first(isc_interfaceiter_t *iter);
+/*!<
+ * \brief Position the iterator on the first interface.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOMORE There are no interfaces.
+ */
+
+isc_result_t
+isc_interfaceiter_current(isc_interfaceiter_t *iter,
+ isc_interface_t *ifdata);
+/*!<
+ * \brief Get information about the interface the iterator is currently
+ * positioned at and store it at *ifdata.
+ *
+ * Requires:
+ *\li The iterator has been successfully positioned using
+ * isc_interface_iter_first() / isc_interface_iter_next().
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ */
+
+isc_result_t
+isc_interfaceiter_next(isc_interfaceiter_t *iter);
+/*!<
+ * \brief Position the iterator on the next interface.
+ *
+ * Requires:
+ * \li The iterator has been successfully positioned using
+ * isc_interface_iter_first() / isc_interface_iter_next().
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOMORE There are no more interfaces.
+ */
+
+void
+isc_interfaceiter_destroy(isc_interfaceiter_t **iterp);
+/*!<
+ * \brief Destroy the iterator.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_INTERFACEITER_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/lang.h b/contrib/ntp/libntp/lib/isc/include/isc/lang.h
new file mode 100644
index 000000000000..8c608669b224
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/lang.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lang.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_LANG_H
+#define ISC_LANG_H 1
+
+/*! \file isc/lang.h */
+
+#ifdef __cplusplus
+#define ISC_LANG_BEGINDECLS extern "C" {
+#define ISC_LANG_ENDDECLS }
+#else
+#define ISC_LANG_BEGINDECLS
+#define ISC_LANG_ENDDECLS
+#endif
+
+#endif /* ISC_LANG_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/lib.h b/contrib/ntp/libntp/lib/isc/include/isc/lib.h
new file mode 100644
index 000000000000..f24fef850169
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/lib.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lib.h,v 1.16 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISC_LIB_H
+#define ISC_LIB_H 1
+
+/*! \file isc/lib.h */
+
+#include <isc/types.h>
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+LIBISC_EXTERNAL_DATA extern isc_msgcat_t *isc_msgcat;
+
+void
+isc_lib_initmsgcat(void);
+/*!<
+ * \brief Initialize the ISC library's message catalog, isc_msgcat, if it
+ * has not already been initialized.
+ */
+
+void
+isc_lib_register(void);
+/*!<
+ * \brief Register the ISC library implementations for some base services
+ * such as memory or event management and handling socket or timer events.
+ * An external application that wants to use the ISC library must call this
+ * function very early in main().
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LIB_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/list.h b/contrib/ntp/libntp/lib/isc/include/isc/list.h
new file mode 100644
index 000000000000..c9bdfc7ad6bc
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/list.h
@@ -0,0 +1,197 @@
+/*
+ * Copyright (C) 2004, 2006, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_LIST_H
+#define ISC_LIST_H 1
+#include <isc/boolean.h>
+#include <isc/assertions.h>
+
+#ifdef ISC_LIST_CHECKINIT
+#define ISC_LINK_INSIST(x) ISC_INSIST(x)
+#else
+#define ISC_LINK_INSIST(x)
+#endif
+
+#define ISC_LIST(type) struct { type *head, *tail; }
+#define ISC_LIST_INIT(list) \
+ do { (list).head = NULL; (list).tail = NULL; } while (0)
+
+#define ISC_LINK(type) struct { type *prev, *next; }
+#define ISC_LINK_INIT_TYPE(elt, link, type) \
+ do { \
+ (elt)->link.prev = (type *)(-1); \
+ (elt)->link.next = (type *)(-1); \
+ } while (0)
+#define ISC_LINK_INIT(elt, link) \
+ ISC_LINK_INIT_TYPE(elt, link, void)
+#define ISC_LINK_LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1))
+
+#define ISC_LIST_HEAD(list) ((list).head)
+#define ISC_LIST_TAIL(list) ((list).tail)
+#define ISC_LIST_EMPTY(list) ISC_TF((list).head == NULL)
+
+#define __ISC_LIST_PREPENDUNSAFE(list, elt, link) \
+ do { \
+ if ((list).head != NULL) \
+ (list).head->link.prev = (elt); \
+ else \
+ (list).tail = (elt); \
+ (elt)->link.prev = NULL; \
+ (elt)->link.next = (list).head; \
+ (list).head = (elt); \
+ } while (0)
+
+#define ISC_LIST_PREPEND(list, elt, link) \
+ do { \
+ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_PREPENDUNSAFE(list, elt, link); \
+ } while (0)
+
+#define ISC_LIST_INITANDPREPEND(list, elt, link) \
+ __ISC_LIST_PREPENDUNSAFE(list, elt, link)
+
+#define __ISC_LIST_APPENDUNSAFE(list, elt, link) \
+ do { \
+ if ((list).tail != NULL) \
+ (list).tail->link.next = (elt); \
+ else \
+ (list).head = (elt); \
+ (elt)->link.prev = (list).tail; \
+ (elt)->link.next = NULL; \
+ (list).tail = (elt); \
+ } while (0)
+
+#define ISC_LIST_APPEND(list, elt, link) \
+ do { \
+ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_APPENDUNSAFE(list, elt, link); \
+ } while (0)
+
+#define ISC_LIST_INITANDAPPEND(list, elt, link) \
+ __ISC_LIST_APPENDUNSAFE(list, elt, link)
+
+#define __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type) \
+ do { \
+ if ((elt)->link.next != NULL) \
+ (elt)->link.next->link.prev = (elt)->link.prev; \
+ else { \
+ ISC_INSIST((list).tail == (elt)); \
+ (list).tail = (elt)->link.prev; \
+ } \
+ if ((elt)->link.prev != NULL) \
+ (elt)->link.prev->link.next = (elt)->link.next; \
+ else { \
+ ISC_INSIST((list).head == (elt)); \
+ (list).head = (elt)->link.next; \
+ } \
+ (elt)->link.prev = (type *)(-1); \
+ (elt)->link.next = (type *)(-1); \
+ } while (0)
+
+#define __ISC_LIST_UNLINKUNSAFE(list, elt, link) \
+ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void)
+
+#define ISC_LIST_UNLINK_TYPE(list, elt, link, type) \
+ do { \
+ ISC_LINK_INSIST(ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type); \
+ } while (0)
+#define ISC_LIST_UNLINK(list, elt, link) \
+ ISC_LIST_UNLINK_TYPE(list, elt, link, void)
+
+#define ISC_LIST_PREV(elt, link) ((elt)->link.prev)
+#define ISC_LIST_NEXT(elt, link) ((elt)->link.next)
+
+#define __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link) \
+ do { \
+ if ((before)->link.prev == NULL) \
+ ISC_LIST_PREPEND(list, elt, link); \
+ else { \
+ (elt)->link.prev = (before)->link.prev; \
+ (before)->link.prev = (elt); \
+ (elt)->link.prev->link.next = (elt); \
+ (elt)->link.next = (before); \
+ } \
+ } while (0)
+
+#define ISC_LIST_INSERTBEFORE(list, before, elt, link) \
+ do { \
+ ISC_LINK_INSIST(ISC_LINK_LINKED(before, link)); \
+ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_INSERTBEFOREUNSAFE(list, before, elt, link); \
+ } while (0)
+
+#define __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link) \
+ do { \
+ if ((after)->link.next == NULL) \
+ ISC_LIST_APPEND(list, elt, link); \
+ else { \
+ (elt)->link.next = (after)->link.next; \
+ (after)->link.next = (elt); \
+ (elt)->link.next->link.prev = (elt); \
+ (elt)->link.prev = (after); \
+ } \
+ } while (0)
+
+#define ISC_LIST_INSERTAFTER(list, after, elt, link) \
+ do { \
+ ISC_LINK_INSIST(ISC_LINK_LINKED(after, link)); \
+ ISC_LINK_INSIST(!ISC_LINK_LINKED(elt, link)); \
+ __ISC_LIST_INSERTAFTERUNSAFE(list, after, elt, link); \
+ } while (0)
+
+#define ISC_LIST_APPENDLIST(list1, list2, link) \
+ do { \
+ if (ISC_LIST_EMPTY(list1)) \
+ (list1) = (list2); \
+ else if (!ISC_LIST_EMPTY(list2)) { \
+ (list1).tail->link.next = (list2).head; \
+ (list2).head->link.prev = (list1).tail; \
+ (list1).tail = (list2).tail; \
+ } \
+ (list2).head = NULL; \
+ (list2).tail = NULL; \
+ } while (0)
+
+#define ISC_LIST_PREPENDLIST(list1, list2, link) \
+ do { \
+ if (ISC_LIST_EMPTY(list1)) \
+ (list1) = (list2); \
+ else if (!ISC_LIST_EMPTY(list2)) { \
+ (list2).tail->link.next = (list1).head; \
+ (list1).head->link.prev = (list2).tail; \
+ (list1).head = (list2).head; \
+ } \
+ (list2).head = NULL; \
+ (list2).tail = NULL; \
+ } while (0)
+
+#define ISC_LIST_ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link)
+#define __ISC_LIST_ENQUEUEUNSAFE(list, elt, link) \
+ __ISC_LIST_APPENDUNSAFE(list, elt, link)
+#define ISC_LIST_DEQUEUE(list, elt, link) \
+ ISC_LIST_UNLINK_TYPE(list, elt, link, void)
+#define ISC_LIST_DEQUEUE_TYPE(list, elt, link, type) \
+ ISC_LIST_UNLINK_TYPE(list, elt, link, type)
+#define __ISC_LIST_DEQUEUEUNSAFE(list, elt, link) \
+ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, void)
+#define __ISC_LIST_DEQUEUEUNSAFE_TYPE(list, elt, link, type) \
+ __ISC_LIST_UNLINKUNSAFE_TYPE(list, elt, link, type)
+
+#endif /* ISC_LIST_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/log.h b/contrib/ntp/libntp/lib/isc/include/isc/log.h
new file mode 100644
index 000000000000..741c5324290c
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/log.h
@@ -0,0 +1,914 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: log.h,v 1.59 2009/02/16 02:01:16 marka Exp $ */
+
+#ifndef ISC_LOG_H
+#define ISC_LOG_H 1
+
+/*! \file isc/log.h */
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <syslog.h> /* XXXDCL NT */
+
+#include <isc/formatcheck.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+/*@{*/
+/*!
+ * \brief Severity levels, patterned after Unix's syslog levels.
+ *
+ */
+#define ISC_LOG_DEBUG(level) (level)
+/*!
+ * #ISC_LOG_DYNAMIC can only be used for defining channels with
+ * isc_log_createchannel(), not to specify a level in isc_log_write().
+ */
+#define ISC_LOG_DYNAMIC 0
+#define ISC_LOG_INFO (-1)
+#define ISC_LOG_NOTICE (-2)
+#define ISC_LOG_WARNING (-3)
+#define ISC_LOG_ERROR (-4)
+#define ISC_LOG_CRITICAL (-5)
+/*@}*/
+
+/*@{*/
+/*!
+ * \brief Destinations.
+ */
+#define ISC_LOG_TONULL 1
+#define ISC_LOG_TOSYSLOG 2
+#define ISC_LOG_TOFILE 3
+#define ISC_LOG_TOFILEDESC 4
+/*@}*/
+
+/*@{*/
+/*%
+ * Channel flags.
+ */
+#define ISC_LOG_PRINTTIME 0x0001
+#define ISC_LOG_PRINTLEVEL 0x0002
+#define ISC_LOG_PRINTCATEGORY 0x0004
+#define ISC_LOG_PRINTMODULE 0x0008
+#define ISC_LOG_PRINTTAG 0x0010
+#define ISC_LOG_PRINTALL 0x001F
+#define ISC_LOG_DEBUGONLY 0x1000
+#define ISC_LOG_OPENERR 0x8000 /* internal */
+/*@}*/
+
+/*@{*/
+/*!
+ * \brief Other options.
+ *
+ * XXXDCL INFINITE doesn't yet work. Arguably it isn't needed, but
+ * since I am intend to make large number of versions work efficiently,
+ * INFINITE is going to be trivial to add to that.
+ */
+#define ISC_LOG_ROLLINFINITE (-1)
+#define ISC_LOG_ROLLNEVER (-2)
+/*@}*/
+
+/*!
+ * \brief Used to name the categories used by a library.
+ *
+ * An array of isc_logcategory
+ * structures names each category, and the id value is initialized by calling
+ * isc_log_registercategories.
+ */
+struct isc_logcategory {
+ const char *name;
+ unsigned int id;
+};
+
+/*%
+ * Similar to isc_logcategory, but for all the modules a library defines.
+ */
+struct isc_logmodule {
+ const char *name;
+ unsigned int id;
+};
+
+/*%
+ * The isc_logfile structure is initialized as part of an isc_logdestination
+ * before calling isc_log_createchannel().
+ *
+ * When defining an #ISC_LOG_TOFILE
+ * channel the name, versions and maximum_size should be set before calling
+ * isc_log_createchannel(). To define an #ISC_LOG_TOFILEDESC channel set only
+ * the stream before the call.
+ *
+ * Setting maximum_size to zero implies no maximum.
+ */
+typedef struct isc_logfile {
+ FILE *stream; /*%< Initialized to NULL for #ISC_LOG_TOFILE. */
+ const char *name; /*%< NULL for #ISC_LOG_TOFILEDESC. */
+ int versions; /* >= 0, #ISC_LOG_ROLLNEVER, #ISC_LOG_ROLLINFINITE. */
+ /*%
+ * stdio's ftell is standardized to return a long, which may well not
+ * be big enough for the largest file supportable by the operating
+ * system (though it is _probably_ big enough for the largest log
+ * anyone would want). st_size returned by fstat should be typedef'd
+ * to a size large enough for the largest possible file on a system.
+ */
+ isc_offset_t maximum_size;
+ isc_boolean_t maximum_reached; /*%< Private. */
+} isc_logfile_t;
+
+/*%
+ * Passed to isc_log_createchannel to define the attributes of either
+ * a stdio or a syslog log.
+ */
+typedef union isc_logdestination {
+ isc_logfile_t file;
+ int facility; /* XXXDCL NT */
+} isc_logdestination_t;
+
+/*@{*/
+/*%
+ * The built-in categories of libisc.
+ *
+ * Each library registering categories should provide library_LOGCATEGORY_name
+ * definitions with indexes into its isc_logcategory structure corresponding to
+ * the order of the names.
+ */
+LIBISC_EXTERNAL_DATA extern isc_logcategory_t isc_categories[];
+LIBISC_EXTERNAL_DATA extern isc_log_t *isc_lctx;
+LIBISC_EXTERNAL_DATA extern isc_logmodule_t isc_modules[];
+/*@}*/
+
+/*@{*/
+/*%
+ * Do not log directly to DEFAULT. Use another category. When in doubt,
+ * use GENERAL.
+ */
+#define ISC_LOGCATEGORY_DEFAULT (&isc_categories[0])
+#define ISC_LOGCATEGORY_GENERAL (&isc_categories[1])
+/*@}*/
+
+#define ISC_LOGMODULE_SOCKET (&isc_modules[0])
+#define ISC_LOGMODULE_TIME (&isc_modules[1])
+#define ISC_LOGMODULE_INTERFACE (&isc_modules[2])
+#define ISC_LOGMODULE_TIMER (&isc_modules[3])
+#define ISC_LOGMODULE_FILE (&isc_modules[4])
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp);
+/*%<
+ * Establish a new logging context, with default channels.
+ *
+ * Notes:
+ *\li isc_log_create() calls isc_logconfig_create(), so see its comment
+ * below for more information.
+ *
+ * Requires:
+ *\li mctx is a valid memory context.
+ *\li lctxp is not null and *lctxp is null.
+ *\li lcfgp is null or lcfgp is not null and *lcfgp is null.
+ *
+ * Ensures:
+ *\li *lctxp will point to a valid logging context if all of the necessary
+ * memory was allocated, or NULL otherwise.
+ *\li *lcfgp will point to a valid logging configuration if all of the
+ * necessary memory was allocated, or NULL otherwise.
+ *\li On failure, no additional memory is allocated.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ */
+
+isc_result_t
+isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp);
+/*%<
+ * Create the data structure that holds all of the configurable information
+ * about where messages are actually supposed to be sent -- the information
+ * that could changed based on some configuration file, as opposed to the
+ * the category/module specification of isc_log_[v]write[1] that is compiled
+ * into a program, or the debug_level which is dynamic state information.
+ *
+ * Notes:
+ *\li It is necessary to specify the logging context the configuration
+ * will be used with because the number of categories and modules
+ * needs to be known in order to set the configuration. However,
+ * the configuration is not used by the logging context until the
+ * isc_logconfig_use function is called.
+ *
+ *\li The memory context used for operations that allocate memory for
+ * the configuration is that of the logging context, as specified
+ * in the isc_log_create call.
+ *
+ *\li Four default channels are established:
+ *\verbatim
+ * default_syslog
+ * - log to syslog's daemon facility #ISC_LOG_INFO or higher
+ * default_stderr
+ * - log to stderr #ISC_LOG_INFO or higher
+ * default_debug
+ * - log to stderr #ISC_LOG_DEBUG dynamically
+ * null
+ * - log nothing
+ *\endverbatim
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *\li lcftp is not null and *lcfgp is null.
+ *
+ * Ensures:
+ *\li *lcfgp will point to a valid logging context if all of the necessary
+ * memory was allocated, or NULL otherwise.
+ *\li On failure, no additional memory is allocated.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ */
+
+isc_logconfig_t *
+isc_logconfig_get(isc_log_t *lctx);
+/*%<
+ * Returns a pointer to the configuration currently in use by the log context.
+ *
+ * Requires:
+ *\li lctx is a valid context.
+ *
+ * Ensures:
+ *\li The configuration pointer is non-null.
+ *
+ * Returns:
+ *\li The configuration pointer.
+ */
+
+isc_result_t
+isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg);
+/*%<
+ * Associate a new configuration with a logging context.
+ *
+ * Notes:
+ *\li This is thread safe. The logging context will lock a mutex
+ * before attempting to swap in the new configuration, and isc_log_doit
+ * (the internal function used by all of isc_log_[v]write[1]) locks
+ * the same lock for the duration of its use of the configuration.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *\li lcfg is a valid logging configuration.
+ *\li lctx is the same configuration given to isc_logconfig_create
+ * when the configuration was created.
+ *
+ * Ensures:
+ *\li Future calls to isc_log_write will use the new configuration.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ */
+
+void
+isc_log_destroy(isc_log_t **lctxp);
+/*%<
+ * Deallocate the memory associated with a logging context.
+ *
+ * Requires:
+ *\li *lctx is a valid logging context.
+ *
+ * Ensures:
+ *\li All of the memory associated with the logging context is returned
+ * to the free memory pool.
+ *
+ *\li Any open files are closed.
+ *
+ *\li The logging context is marked as invalid.
+ */
+
+void
+isc_logconfig_destroy(isc_logconfig_t **lcfgp);
+/*%<
+ * Destroy a logging configuration.
+ *
+ * Notes:
+ *\li This function cannot be used directly with the return value of
+ * isc_logconfig_get, because a logging context must always have
+ * a valid configuration associated with it.
+ *
+ * Requires:
+ *\li lcfgp is not null and *lcfgp is a valid logging configuration.
+ *\li The logging configuration is not in use by an existing logging context.
+ *
+ * Ensures:
+ *\li All memory allocated for the configuration is freed.
+ *
+ *\li The configuration is marked as invalid.
+ */
+
+void
+isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]);
+/*%<
+ * Identify logging categories a library will use.
+ *
+ * Notes:
+ *\li A category should only be registered once, but no mechanism enforces
+ * this rule.
+ *
+ *\li The end of the categories array is identified by a NULL name.
+ *
+ *\li Because the name is used by #ISC_LOG_PRINTCATEGORY, it should not
+ * be altered or destroyed after isc_log_registercategories().
+ *
+ *\li Because each element of the categories array is used by
+ * isc_log_categorybyname, it should not be altered or destroyed
+ * after registration.
+ *
+ *\li The value of the id integer in each structure is overwritten
+ * by this function, and so id need not be initialized to any particular
+ * value prior to the function call.
+ *
+ *\li A subsequent call to isc_log_registercategories with the same
+ * logging context (but new categories) will cause the last
+ * element of the categories array from the prior call to have
+ * its "name" member changed from NULL to point to the new
+ * categories array, and its "id" member set to UINT_MAX.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *\li categories != NULL.
+ *\li categories[0].name != NULL.
+ *
+ * Ensures:
+ * \li There are references to each category in the logging context,
+ * so they can be used with isc_log_usechannel() and isc_log_write().
+ */
+
+void
+isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]);
+/*%<
+ * Identify logging categories a library will use.
+ *
+ * Notes:
+ *\li A module should only be registered once, but no mechanism enforces
+ * this rule.
+ *
+ *\li The end of the modules array is identified by a NULL name.
+ *
+ *\li Because the name is used by #ISC_LOG_PRINTMODULE, it should not
+ * be altered or destroyed after isc_log_registermodules().
+ *
+ *\li Because each element of the modules array is used by
+ * isc_log_modulebyname, it should not be altered or destroyed
+ * after registration.
+ *
+ *\li The value of the id integer in each structure is overwritten
+ * by this function, and so id need not be initialized to any particular
+ * value prior to the function call.
+ *
+ *\li A subsequent call to isc_log_registermodules with the same
+ * logging context (but new modules) will cause the last
+ * element of the modules array from the prior call to have
+ * its "name" member changed from NULL to point to the new
+ * modules array, and its "id" member set to UINT_MAX.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *\li modules != NULL.
+ *\li modules[0].name != NULL;
+ *
+ * Ensures:
+ *\li Each module has a reference in the logging context, so they can be
+ * used with isc_log_usechannel() and isc_log_write().
+ */
+
+isc_result_t
+isc_log_createchannel(isc_logconfig_t *lcfg, const char *name,
+ unsigned int type, int level,
+ const isc_logdestination_t *destination,
+ unsigned int flags);
+/*%<
+ * Specify the parameters of a logging channel.
+ *
+ * Notes:
+ *\li The name argument is copied to memory in the logging context, so
+ * it can be altered or destroyed after isc_log_createchannel().
+ *
+ *\li Defining a very large number of channels will have a performance
+ * impact on isc_log_usechannel(), since the names are searched
+ * linearly until a match is made. This same issue does not affect
+ * isc_log_write, however.
+ *
+ *\li Channel names can be redefined; this is primarily useful for programs
+ * that want their own definition of default_syslog, default_debug
+ * and default_stderr.
+ *
+ *\li Any channel that is redefined will not affect logging that was
+ * already directed to its original definition, _except_ for the
+ * default_stderr channel. This case is handled specially so that
+ * the default logging category can be changed by redefining
+ * default_stderr. (XXXDCL Though now that I think of it, the default
+ * logging category can be changed with only one additional function
+ * call by defining a new channel and then calling isc_log_usechannel()
+ * for #ISC_LOGCATEGORY_DEFAULT.)
+ *
+ *\li Specifying #ISC_LOG_PRINTTIME or #ISC_LOG_PRINTTAG for syslog is allowed,
+ * but probably not what you wanted to do.
+ *
+ * #ISC_LOG_DEBUGONLY will mark the channel as usable only when the
+ * debug level of the logging context (see isc_log_setdebuglevel)
+ * is non-zero.
+ *
+ * Requires:
+ *\li lcfg is a valid logging configuration.
+ *
+ *\li name is not NULL.
+ *
+ *\li type is #ISC_LOG_TOSYSLOG, #ISC_LOG_TOFILE, #ISC_LOG_TOFILEDESC or
+ * #ISC_LOG_TONULL.
+ *
+ *\li destination is not NULL unless type is #ISC_LOG_TONULL.
+ *
+ *\li level is >= #ISC_LOG_CRITICAL (the most negative logging level).
+ *
+ *\li flags does not include any bits aside from the ISC_LOG_PRINT* bits
+ * or #ISC_LOG_DEBUGONLY.
+ *
+ * Ensures:
+ *\li #ISC_R_SUCCESS
+ * A channel with the given name is usable with
+ * isc_log_usechannel().
+ *
+ *\li #ISC_R_NOMEMORY or #ISC_R_UNEXPECTED
+ * No additional memory is being used by the logging context.
+ * Any channel that previously existed with the given name
+ * is not redefined.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ *\li #ISC_R_UNEXPECTED type was out of range and REQUIRE()
+ * was disabled.
+ */
+
+isc_result_t
+isc_log_usechannel(isc_logconfig_t *lcfg, const char *name,
+ const isc_logcategory_t *category,
+ const isc_logmodule_t *module);
+/*%<
+ * Associate a named logging channel with a category and module that
+ * will use it.
+ *
+ * Notes:
+ *\li The name is searched for linearly in the set of known channel names
+ * until a match is found. (Note the performance impact of a very large
+ * number of named channels.) When multiple channels of the same
+ * name are defined, the most recent definition is found.
+ *
+ *\li Specifying a very large number of channels for a category will have
+ * a moderate impact on performance in isc_log_write(), as each
+ * call looks up the category for the start of a linked list, which
+ * it follows all the way to the end to find matching modules. The
+ * test for matching modules is integral, though.
+ *
+ *\li If category is NULL, then the channel is associated with the indicated
+ * module for all known categories (including the "default" category).
+ *
+ *\li If module is NULL, then the channel is associated with every module
+ * that uses that category.
+ *
+ *\li Passing both category and module as NULL would make every log message
+ * use the indicated channel.
+ *
+ * \li Specifying a channel that is #ISC_LOG_TONULL for a category/module pair
+ * has no effect on any other channels associated with that pair,
+ * regardless of ordering. Thus you cannot use it to "mask out" one
+ * category/module pair when you have specified some other channel that
+ * is also used by that category/module pair.
+ *
+ * Requires:
+ *\li lcfg is a valid logging configuration.
+ *
+ *\li category is NULL or has an id that is in the range of known ids.
+ *
+ * module is NULL or has an id that is in the range of known ids.
+ *
+ * Ensures:
+ *\li #ISC_R_SUCCESS
+ * The channel will be used by the indicated category/module
+ * arguments.
+ *
+ *\li #ISC_R_NOMEMORY
+ * If assignment for a specific category has been requested,
+ * the channel has not been associated with the indicated
+ * category/module arguments and no additional memory is
+ * used by the logging context.
+ * If assignment for all categories has been requested
+ * then _some_ may have succeeded (starting with category
+ * "default" and progressing through the order of categories
+ * passed to isc_log_registercategories()) and additional memory
+ * is being used by whatever assignments succeeded.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource limit: Out of memory
+ */
+
+/* Attention: next four comments PRECEED code */
+/*!
+ * \brief
+ * Write a message to the log channels.
+ *
+ * Notes:
+ *\li Log messages containing natural language text should be logged with
+ * isc_log_iwrite() to allow for localization.
+ *
+ *\li lctx can be NULL; this is allowed so that programs which use
+ * libraries that use the ISC logging system are not required to
+ * also use it.
+ *
+ *\li The format argument is a printf(3) string, with additional arguments
+ * as necessary.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ *\li The category and module arguments must have ids that are in the
+ * range of known ids, as established by isc_log_registercategories()
+ * and isc_log_registermodules().
+ *
+ *\li level != #ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define
+ * channels, and explicit debugging level must be identified for
+ * isc_log_write() via ISC_LOG_DEBUG(level).
+ *
+ *\li format != NULL.
+ *
+ * Ensures:
+ *\li The log message is written to every channel associated with the
+ * indicated category/module pair.
+ *
+ * Returns:
+ *\li Nothing. Failure to log a message is not construed as a
+ * meaningful error.
+ */
+void
+isc_log_write(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, ...)
+
+ISC_FORMAT_PRINTF(5, 6);
+
+/*%
+ * Write a message to the log channels.
+ *
+ * Notes:
+ *\li lctx can be NULL; this is allowed so that programs which use
+ * libraries that use the ISC logging system are not required to
+ * also use it.
+ *
+ *\li The format argument is a printf(3) string, with additional arguments
+ * as necessary.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ *\li The category and module arguments must have ids that are in the
+ * range of known ids, as established by isc_log_registercategories()
+ * and isc_log_registermodules().
+ *
+ *\li level != #ISC_LOG_DYNAMIC. ISC_LOG_DYNAMIC is used only to define
+ * channels, and explicit debugging level must be identified for
+ * isc_log_write() via ISC_LOG_DEBUG(level).
+ *
+ *\li format != NULL.
+ *
+ * Ensures:
+ *\li The log message is written to every channel associated with the
+ * indicated category/module pair.
+ *
+ * Returns:
+ *\li Nothing. Failure to log a message is not construed as a
+ * meaningful error.
+ */
+void
+isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, va_list args)
+
+ISC_FORMAT_PRINTF(5, 0);
+
+/*%
+ * Write a message to the log channels, pruning duplicates that occur within
+ * a configurable amount of seconds (see isc_log_[sg]etduplicateinterval).
+ * This function is otherwise identical to isc_log_write().
+ */
+void
+isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *format, ...)
+
+ISC_FORMAT_PRINTF(5, 6);
+
+/*%
+ * Write a message to the log channels, pruning duplicates that occur within
+ * a configurable amount of seconds (see isc_log_[sg]etduplicateinterval).
+ * This function is otherwise identical to isc_log_vwrite().
+ */
+void
+isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *format,
+ va_list args)
+
+ISC_FORMAT_PRINTF(5, 0);
+
+/*%
+ * These are four internationalized versions of the isc_log_[v]write[1]
+ * functions.
+ *
+ * The only difference is that they take arguments for a message
+ * catalog, message set, and message number, all immediately preceding the
+ * format argument. The format argument becomes the default text, a la
+ * isc_msgcat_get. If the message catalog is NULL, no lookup is attempted
+ * for a message -- which makes the message set and message number irrelevant,
+ * and the non-internationalized call should have probably been used instead.
+ *
+ * Yes, that means there are now *eight* interfaces to logging a message.
+ * Sheesh. Make the madness stop!
+ */
+/*@{*/
+void
+isc_log_iwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int message,
+ const char *format, ...)
+ISC_FORMAT_PRINTF(8, 9);
+
+void
+isc_log_ivwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int message,
+ const char *format, va_list args)
+ISC_FORMAT_PRINTF(8, 0);
+
+void
+isc_log_iwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int message,
+ const char *format, ...)
+ISC_FORMAT_PRINTF(8, 9);
+
+void
+isc_log_ivwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int message,
+ const char *format, va_list args)
+ISC_FORMAT_PRINTF(8, 0);
+/*@}*/
+
+void
+isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level);
+/*%<
+ * Set the debugging level used for logging.
+ *
+ * Notes:
+ *\li Setting the debugging level to 0 disables debugging log messages.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ * Ensures:
+ *\li The debugging level is set to the requested value.
+ */
+
+unsigned int
+isc_log_getdebuglevel(isc_log_t *lctx);
+/*%<
+ * Get the current debugging level.
+ *
+ * Notes:
+ *\li This is provided so that a program can have a notion of
+ * "increment debugging level" or "decrement debugging level"
+ * without needing to keep track of what the current level is.
+ *
+ *\li A return value of 0 indicates that debugging messages are disabled.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ * Ensures:
+ *\li The current logging debugging level is returned.
+ */
+
+isc_boolean_t
+isc_log_wouldlog(isc_log_t *lctx, int level);
+/*%<
+ * Determine whether logging something to 'lctx' at 'level' would
+ * actually cause something to be logged somewhere.
+ *
+ * If #ISC_FALSE is returned, it is guaranteed that nothing would
+ * be logged, allowing the caller to omit unnecessary
+ * isc_log_write() calls and possible message preformatting.
+ */
+
+void
+isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval);
+/*%<
+ * Set the interval over which duplicate log messages will be ignored
+ * by isc_log_[v]write1(), in seconds.
+ *
+ * Notes:
+ *\li Increasing the duplicate interval from X to Y will not necessarily
+ * filter out duplicates of messages logged in Y - X seconds since the
+ * increase. (Example: Message1 is logged at midnight. Message2
+ * is logged at 00:01:00, when the interval is only 30 seconds, causing
+ * Message1 to be expired from the log message history. Then the interval
+ * is increased to 3000 (five minutes) and at 00:04:00 Message1 is logged
+ * again. It will appear the second time even though less than five
+ * passed since the first occurrence.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ */
+
+unsigned int
+isc_log_getduplicateinterval(isc_logconfig_t *lcfg);
+/*%<
+ * Get the current duplicate filtering interval.
+ *
+ * Requires:
+ *\li lctx is a valid logging context.
+ *
+ * Returns:
+ *\li The current duplicate filtering interval.
+ */
+
+isc_result_t
+isc_log_settag(isc_logconfig_t *lcfg, const char *tag);
+/*%<
+ * Set the program name or other identifier for #ISC_LOG_PRINTTAG.
+ *
+ * Requires:
+ *\li lcfg is a valid logging configuration.
+ *
+ * Notes:
+ *\li If this function has not set the tag to a non-NULL, non-empty value,
+ * then the #ISC_LOG_PRINTTAG channel flag will not print anything.
+ * Unlike some implementations of syslog on Unix systems, you *must* set
+ * the tag in order to get it logged. It is not implicitly derived from
+ * the program name (which is pretty impossible to infer portably).
+ *
+ *\li Setting the tag to NULL or the empty string will also cause the
+ * #ISC_LOG_PRINTTAG channel flag to not print anything. If tag equals the
+ * empty string, calls to isc_log_gettag will return NULL.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success
+ *\li #ISC_R_NOMEMORY Resource Limit: Out of memory
+ *
+ * XXXDCL when creating a new isc_logconfig_t, it might be nice if the tag
+ * of the currently active isc_logconfig_t was inherited. this does not
+ * currently happen.
+ */
+
+char *
+isc_log_gettag(isc_logconfig_t *lcfg);
+/*%<
+ * Get the current identifier printed with #ISC_LOG_PRINTTAG.
+ *
+ * Requires:
+ *\li lcfg is a valid logging configuration.
+ *
+ * Notes:
+ *\li Since isc_log_settag() will not associate a zero-length string
+ * with the logging configuration, attempts to do so will cause
+ * this function to return NULL. However, a determined programmer
+ * will observe that (currently) a tag of length greater than zero
+ * could be set, and then modified to be zero length.
+ *
+ * Returns:
+ *\li A pointer to the current identifier, or NULL if none has been set.
+ */
+
+void
+isc_log_opensyslog(const char *tag, int options, int facility);
+/*%<
+ * Initialize syslog logging.
+ *
+ * Notes:
+ *\li XXXDCL NT
+ * This is currently equivalent to openlog(), but is not going to remain
+ * that way. In the meantime, the arguments are all identical to
+ * those used by openlog(3), as follows:
+ *
+ * \code
+ * tag: The string to use in the position of the program
+ * name in syslog messages. Most (all?) syslogs
+ * will use basename(argv[0]) if tag is NULL.
+ *
+ * options: LOG_CONS, LOG_PID, LOG_NDELAY ... whatever your
+ * syslog supports.
+ *
+ * facility: The default syslog facility. This is irrelevant
+ * since isc_log_write will ALWAYS use the channel's
+ * declared facility.
+ * \endcode
+ *
+ *\li Zero effort has been made (yet) to accommodate systems with openlog()
+ * that only takes two arguments, or to identify valid syslog
+ * facilities or options for any given architecture.
+ *
+ *\li It is necessary to call isc_log_opensyslog() to initialize
+ * syslogging on machines which do not support network connections to
+ * syslogd because they require a Unix domain socket to be used. Since
+ * this is a chore to determine at run-time, it is suggested that it
+ * always be called by programs using the ISC logging system.
+ *
+ * Requires:
+ *\li Nothing.
+ *
+ * Ensures:
+ *\li openlog() is called to initialize the syslog system.
+ */
+
+void
+isc_log_closefilelogs(isc_log_t *lctx);
+/*%<
+ * Close all open files used by #ISC_LOG_TOFILE channels.
+ *
+ * Notes:
+ *\li This function is provided for programs that want to use their own
+ * log rolling mechanism rather than the one provided internally.
+ * For example, a program that wanted to keep daily logs would define
+ * a channel which used #ISC_LOG_ROLLNEVER, then once a day would
+ * rename the log file and call isc_log_closefilelogs().
+ *
+ *\li #ISC_LOG_TOFILEDESC channels are unaffected.
+ *
+ * Requires:
+ *\li lctx is a valid context.
+ *
+ * Ensures:
+ *\li The open files are closed and will be reopened when they are
+ * next needed.
+ */
+
+isc_logcategory_t *
+isc_log_categorybyname(isc_log_t *lctx, const char *name);
+/*%<
+ * Find a category by its name.
+ *
+ * Notes:
+ *\li The string name of a category is not required to be unique.
+ *
+ * Requires:
+ *\li lctx is a valid context.
+ *\li name is not NULL.
+ *
+ * Returns:
+ *\li A pointer to the _first_ isc_logcategory_t structure used by "name".
+ *
+ *\li NULL if no category exists by that name.
+ */
+
+isc_logmodule_t *
+isc_log_modulebyname(isc_log_t *lctx, const char *name);
+/*%<
+ * Find a module by its name.
+ *
+ * Notes:
+ *\li The string name of a module is not required to be unique.
+ *
+ * Requires:
+ *\li lctx is a valid context.
+ *\li name is not NULL.
+ *
+ * Returns:
+ *\li A pointer to the _first_ isc_logmodule_t structure used by "name".
+ *
+ *\li NULL if no module exists by that name.
+ */
+
+void
+isc_log_setcontext(isc_log_t *lctx);
+/*%<
+ * Sets the context used by the libisc for logging.
+ *
+ * Requires:
+ *\li lctx be a valid context.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LOG_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/magic.h b/contrib/ntp/libntp/lib/isc/include/isc/magic.h
new file mode 100644
index 000000000000..073de90dcc92
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/magic.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: magic.h,v 1.18 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_MAGIC_H
+#define ISC_MAGIC_H 1
+
+/*! \file isc/magic.h */
+
+typedef struct {
+ unsigned int magic;
+} isc__magic_t;
+
+
+/*%
+ * To use this macro the magic number MUST be the first thing in the
+ * structure, and MUST be of type "unsigned int".
+ * The intent of this is to allow magic numbers to be checked even though
+ * the object is otherwise opaque.
+ */
+#define ISC_MAGIC_VALID(a,b) (((a) != NULL) && \
+ (((const isc__magic_t *)(a))->magic == (b)))
+
+#define ISC_MAGIC(a, b, c, d) ((a) << 24 | (b) << 16 | (c) << 8 | (d))
+
+#endif /* ISC_MAGIC_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/md5.h b/contrib/ntp/libntp/lib/isc/include/isc/md5.h
new file mode 100644
index 000000000000..dfa586d0a3b0
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/md5.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2004-2007, 2009, 2010 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: md5.h,v 1.20 2010/01/07 23:48:54 tbox Exp $ */
+
+/*! \file isc/md5.h
+ * \brief This is the header file for the MD5 message-digest algorithm.
+ *
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * Changed so as no longer to depend on Colin Plumb's `usual.h'
+ * header definitions; now uses stuff from dpkg's config.h
+ * - Ian Jackson <ijackson@nyx.cs.du.edu>.
+ * Still in the public domain.
+ */
+
+#ifndef ISC_MD5_H
+#define ISC_MD5_H 1
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#define ISC_MD5_DIGESTLENGTH 16U
+#define ISC_MD5_BLOCK_LENGTH 64U
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/evp.h>
+
+typedef EVP_MD_CTX isc_md5_t;
+
+#else
+
+typedef struct {
+ isc_uint32_t buf[4];
+ isc_uint32_t bytes[2];
+ isc_uint32_t in[16];
+} isc_md5_t;
+#endif
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_md5_init(isc_md5_t *ctx);
+
+void
+isc_md5_invalidate(isc_md5_t *ctx);
+
+void
+isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len);
+
+void
+isc_md5_final(isc_md5_t *ctx, unsigned char *digest);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_MD5_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/msgcat.h b/contrib/ntp/libntp/lib/isc/include/isc/msgcat.h
new file mode 100644
index 000000000000..fe3d336825f0
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/msgcat.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: msgcat.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_MSGCAT_H
+#define ISC_MSGCAT_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/msgcat.h
+ * \brief The ISC Message Catalog
+ * aids internationalization of applications by allowing
+ * messages to be retrieved from locale-specific files instead of
+ * hardwiring them into the application. This allows translations of
+ * messages appropriate to the locale to be supplied without recompiling
+ * the application.
+ *
+ * Notes:
+ *\li It's very important that message catalogs work, even if only the
+ * default_text can be used.
+ *
+ * MP:
+ *\li The caller must ensure appropriate synchronization of
+ * isc_msgcat_open() and isc_msgcat_close(). isc_msgcat_get()
+ * ensures appropriate synchronization.
+ *
+ * Reliability:
+ *\li No anticipated impact.
+ *
+ * Resources:
+ *\li TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/*****
+ ***** Imports
+ *****/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*****
+ ***** Methods
+ *****/
+
+void
+isc_msgcat_open(const char *name, isc_msgcat_t **msgcatp);
+/*%<
+ * Open a message catalog.
+ *
+ * Notes:
+ *
+ *\li If memory cannot be allocated or other failures occur, *msgcatp
+ * will be set to NULL. If a NULL msgcat is given to isc_msgcat_get(),
+ * the default_text will be returned, ensuring that some message text
+ * will be available, no matter what's going wrong.
+ *
+ * Requires:
+ *
+ *\li 'name' is a valid string.
+ *
+ *\li msgcatp != NULL && *msgcatp == NULL
+ */
+
+void
+isc_msgcat_close(isc_msgcat_t **msgcatp);
+/*%<
+ * Close a message catalog.
+ *
+ * Notes:
+ *
+ *\li Any string pointers returned by prior calls to isc_msgcat_get() are
+ * invalid after isc_msgcat_close() has been called and must not be
+ * used.
+ *
+ * Requires:
+ *
+ *\li *msgcatp is a valid message catalog or is NULL.
+ *
+ * Ensures:
+ *
+ *\li All resources associated with the message catalog are released.
+ *
+ *\li *msgcatp == NULL
+ */
+
+const char *
+isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message,
+ const char *default_text);
+/*%<
+ * Get message 'message' from message set 'set' in 'msgcat'. If it
+ * is not available, use 'default_text'.
+ *
+ * Requires:
+ *
+ *\li 'msgcat' is a valid message catalog or is NULL.
+ *
+ *\li set > 0
+ *
+ *\li message > 0
+ *
+ *\li 'default_text' is a valid string.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_MSGCAT_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/msgs.h b/contrib/ntp/libntp/lib/isc/include/isc/msgs.h
new file mode 100644
index 000000000000..60c5c7caf882
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/msgs.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: msgs.h,v 1.19 2009/10/01 23:48:08 tbox Exp $ */
+
+#ifndef ISC_MSGS_H
+#define ISC_MSGS_H 1
+
+/*! \file isc/msgs.h */
+
+#include <isc/lib.h> /* Provide isc_msgcat global variable. */
+#include <isc/msgcat.h> /* Provide isc_msgcat_*() functions. */
+
+/*@{*/
+/*!
+ * \brief Message sets, named per source file, excepting "GENERAL".
+ *
+ * IMPORTANT: The original list is alphabetical, but any new sets must
+ * be added to the end.
+ */
+#define ISC_MSGSET_GENERAL 1
+/* ISC_RESULT_RESULTSET 2 */ /* XXX */
+/* ISC_RESULT_UNAVAILABLESET 3 */ /* XXX */
+#define ISC_MSGSET_APP 4
+#define ISC_MSGSET_COMMANDLINE 5
+#define ISC_MSGSET_ENTROPY 6
+#define ISC_MSGSET_IFITERIOCTL 7
+#define ISC_MSGSET_IFITERSYSCTL 8
+#define ISC_MSGSET_LEX 9
+#define ISC_MSGSET_LOG 10
+#define ISC_MSGSET_MEM 11
+#define ISC_MSGSET_NETADDR 12
+#define ISC_MSGSET_PRINT 13
+#define ISC_MSGSET_RESULT 14
+#define ISC_MSGSET_RWLOCK 15
+#define ISC_MSGSET_SOCKADDR 16
+#define ISC_MSGSET_SOCKET 17
+#define ISC_MSGSET_TASK 18
+#define ISC_MSGSET_TIMER 19
+#define ISC_MSGSET_UTIL 20
+#define ISC_MSGSET_IFITERGETIFADDRS 21
+/*@}*/
+
+/*@{*/
+/*!
+ * Message numbers
+ * are only required to be unique per message set,
+ * but are unique throughout the entire catalog to not be as confusing when
+ * debugging.
+ *
+ * The initial numbering was done by multiply by 100 the set number the
+ * message appears in then adding the incremental message number.
+ */
+#define ISC_MSG_FAILED 101 /*%< "failed" */
+#define ISC_MSG_SUCCEEDED 102 /*%< Compatible with "failed" */
+#define ISC_MSG_SUCCESS 103 /*%< More usual way to say "success" */
+#define ISC_MSG_STARTING 104 /*%< As in "daemon: starting" */
+#define ISC_MSG_STOPING 105 /*%< As in "daemon: stopping" */
+#define ISC_MSG_ENTERING 106 /*%< As in "some_subr: entering" */
+#define ISC_MSG_EXITING 107 /*%< As in "some_subr: exiting" */
+#define ISC_MSG_CALLING 108 /*%< As in "calling some_subr()" */
+#define ISC_MSG_RETURNED 109 /*%< As in "some_subr: returned <foo>" */
+#define ISC_MSG_FATALERROR 110 /*%< "fatal error" */
+#define ISC_MSG_SHUTTINGDOWN 111 /*%< "shutting down" */
+#define ISC_MSG_RUNNING 112 /*%< "running" */
+#define ISC_MSG_WAIT 113 /*%< "wait" */
+#define ISC_MSG_WAITUNTIL 114 /*%< "waituntil" */
+
+#define ISC_MSG_SIGNALSETUP 201 /*%< "handle_signal() %d setup: %s" */
+
+#define ISC_MSG_ILLEGALOPT 301 /*%< "illegal option" */
+#define ISC_MSG_OPTNEEDARG 302 /*%< "option requires an argument" */
+
+#define ISC_MSG_ENTROPYSTATS 401 /*%< "Entropy pool %p: refcnt %u ..." */
+
+#define ISC_MSG_MAKESCANSOCKET 501 /*%< "making interface scan socket: %s" */
+#define ISC_MSG_GETIFCONFIG 502 /*%< "get interface configuration: %s" */
+#define ISC_MSG_BUFFERMAX 503 /*%< "... maximum buffer size exceeded" */
+#define ISC_MSG_GETDESTADDR 504 /*%< "%s: getting destination address: %s" */
+#define ISC_MSG_GETNETMASK 505 /*%< "%s: getting netmask: %s" */
+#define ISC_MSG_GETBCSTADDR 506 /*%< "%s: getting broadcast address: %s" */
+
+#define ISC_MSG_GETIFLISTSIZE 601 /*%< "getting interface list size: ..." */
+#define ISC_MSG_GETIFLIST 602 /*%< "getting interface list: ..." */
+#define ISC_MSG_UNEXPECTEDTYPE 603 /*%< "... unexpected ... message type" */
+
+#define ISC_MSG_UNEXPECTEDSTATE 701 /*%< "Unexpected state %d" */
+
+#define ISC_MSG_BADTIME 801 /*%< "Bad 00 99:99:99.999 " */
+#define ISC_MSG_LEVEL 802 /*%< "level %d: " */
+
+#define ISC_MSG_ADDTRACE 901 /*%< "add %p size %u " */
+#define ISC_MSG_DELTRACE 902 /*%< "del %p size %u " */
+#define ISC_MSG_POOLSTATS 903 /*%< "[Pool statistics]\n" */
+#define ISC_MSG_POOLNAME 904 /*%< "name" */
+#define ISC_MSG_POOLSIZE 905 /*%< "size" */
+#define ISC_MSG_POOLMAXALLOC 906 /*%< "maxalloc" */
+#define ISC_MSG_POOLALLOCATED 907 /*%< "allocated" */
+#define ISC_MSG_POOLFREECOUNT 908 /*%< "freecount" */
+#define ISC_MSG_POOLFREEMAX 909 /*%< "freemax" */
+#define ISC_MSG_POOLFILLCOUNT 910 /*%< "fillcount" */
+#define ISC_MSG_POOLGETS 911 /*%< "gets" */
+#define ISC_MSG_DUMPALLOC 912 /*%< "DUMP OF ALL OUTSTANDING MEMORY ..." */
+#define ISC_MSG_NONE 913 /*%< "\tNone.\n" */
+#define ISC_MSG_PTRFILELINE 914 /*%< "\tptr %p file %s line %u\n" */
+
+#define ISC_MSG_UNKNOWNADDR 1001 /*%< "<unknown address, family %u>" */
+
+#define ISC_MSG_NOLONGDBL 1104 /*%< "long doubles are not supported" */
+
+#define ISC_MSG_PRINTLOCK 1201 /*%< "rwlock %p thread %lu ..." */
+#define ISC_MSG_READ 1202 /*%< "read" */
+#define ISC_MSG_WRITE 1203 /*%< "write" */
+#define ISC_MSG_READING 1204 /*%< "reading" */
+#define ISC_MSG_WRITING 1205 /*%< "writing" */
+#define ISC_MSG_PRELOCK 1206 /*%< "prelock" */
+#define ISC_MSG_POSTLOCK 1207 /*%< "postlock" */
+#define ISC_MSG_PREUNLOCK 1208 /*%< "preunlock" */
+#define ISC_MSG_POSTUNLOCK 1209 /*%< "postunlock" */
+
+#define ISC_MSG_UNKNOWNFAMILY 1301 /*%< "unknown address family: %d" */
+
+#define ISC_MSG_WRITEFAILED 1401 /*%< "write() failed during watcher ..." */
+#define ISC_MSG_READFAILED 1402 /*%< "read() failed during watcher ... " */
+#define ISC_MSG_PROCESSCMSG 1403 /*%< "processing cmsg %p" */
+#define ISC_MSG_IFRECEIVED 1404 /*%< "interface received on ifindex %u" */
+#define ISC_MSG_SENDTODATA 1405 /*%< "sendto pktinfo data, ifindex %u" */
+#define ISC_MSG_DOIORECV 1406 /*%< "doio_recv: recvmsg(%d) %d bytes ..." */
+#define ISC_MSG_PKTRECV 1407 /*%< "packet received correctly" */
+#define ISC_MSG_DESTROYING 1408 /*%< "destroying" */
+#define ISC_MSG_CREATED 1409 /*%< "created" */
+#define ISC_MSG_ACCEPTLOCK 1410 /*%< "internal_accept called, locked ..." */
+#define ISC_MSG_ACCEPTEDCXN 1411 /*%< "accepted connection, new socket %p" */
+#define ISC_MSG_INTERNALRECV 1412 /*%< "internal_recv: task %p got event %p" */
+#define ISC_MSG_INTERNALSEND 1413 /*%< "internal_send: task %p got event %p" */
+#define ISC_MSG_WATCHERMSG 1414 /*%< "watcher got message %d" */
+#define ISC_MSG_SOCKETSREMAIN 1415 /*%< "sockets exist" */
+#define ISC_MSG_PKTINFOPROVIDED 1416 /*%< "pktinfo structure provided, ..." */
+#define ISC_MSG_BOUND 1417 /*%< "bound" */
+#define ISC_MSG_ACCEPTRETURNED 1418 /*%< accept() returned %d/%s */
+#define ISC_MSG_TOOMANYFDS 1419 /*%< %s: too many open file descriptors */
+#define ISC_MSG_ZEROPORT 1420 /*%< dropping source port zero packet */
+#define ISC_MSG_FILTER 1421 /*%< setsockopt(SO_ACCEPTFILTER): %s */
+
+#define ISC_MSG_TOOMANYHANDLES 1422 /*%< %s: too many open WSA event handles: %s */
+#define ISC_MSG_POKED 1423 /*%< "poked flags: %d" */
+
+#define ISC_MSG_AWAKE 1502 /*%< "awake" */
+#define ISC_MSG_WORKING 1503 /*%< "working" */
+#define ISC_MSG_EXECUTE 1504 /*%< "execute action" */
+#define ISC_MSG_EMPTY 1505 /*%< "empty" */
+#define ISC_MSG_DONE 1506 /*%< "done" */
+#define ISC_MSG_QUANTUM 1507 /*%< "quantum" */
+
+#define ISC_MSG_SCHEDULE 1601 /*%< "schedule" */
+#define ISC_MSG_SIGNALSCHED 1602 /*%< "signal (schedule)" */
+#define ISC_MSG_SIGNALDESCHED 1603 /*%< "signal (deschedule)" */
+#define ISC_MSG_SIGNALDESTROY 1604 /*%< "signal (destroy)" */
+#define ISC_MSG_IDLERESCHED 1605 /*%< "idle reschedule" */
+#define ISC_MSG_EVENTNOTALLOC 1606 /*%< "couldn't allocate event" */
+#define ISC_MSG_SCHEDFAIL 1607 /*%< "couldn't schedule timer: %u" */
+#define ISC_MSG_POSTING 1608 /*%< "posting" */
+#define ISC_MSG_WAKEUP 1609 /*%< "wakeup" */
+
+#define ISC_MSG_LOCK 1701 /*%< "LOCK" */
+#define ISC_MSG_LOCKING 1702 /*%< "LOCKING" */
+#define ISC_MSG_LOCKED 1703 /*%< "LOCKED" */
+#define ISC_MSG_UNLOCKED 1704 /*%< "UNLOCKED" */
+#define ISC_MSG_RWLOCK 1705 /*%< "RWLOCK" */
+#define ISC_MSG_RWLOCKED 1706 /*%< "RWLOCKED" */
+#define ISC_MSG_RWUNLOCK 1707 /*%< "RWUNLOCK" */
+#define ISC_MSG_BROADCAST 1708 /*%< "BROADCAST" */
+#define ISC_MSG_SIGNAL 1709 /*%< "SIGNAL" */
+#define ISC_MSG_UTILWAIT 1710 /*%< "WAIT" */
+#define ISC_MSG_WAITED 1711 /*%< "WAITED" */
+
+#define ISC_MSG_GETIFADDRS 1801 /*%< "getting interface addresses: ..." */
+
+/*@}*/
+
+#endif /* ISC_MSGS_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/namespace.h b/contrib/ntp/libntp/lib/isc/include/isc/namespace.h
new file mode 100644
index 000000000000..cd4ec9ad1689
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/namespace.h
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISCAPI_NAMESPACE_H
+#define ISCAPI_NAMESPACE_H 1
+
+/*%
+ * name space conversions
+ */
+
+#ifdef BIND9
+
+#define isc_app_start isc__app_start
+#define isc_app_ctxstart isc__app_ctxstart
+#define isc_app_onrun isc__app_onrun
+#define isc_app_run isc__app_run
+#define isc_app_ctxrun isc__app_ctxrun
+#define isc_app_shutdown isc__app_shutdown
+#define isc_app_ctxfinish isc__app_ctxfinish
+#define isc_app_ctxshutdown isc__app_ctxshutdown
+#define isc_app_ctxsuspend isc__app_ctxsuspend
+#define isc_app_reload isc__app_reload
+#define isc_app_finish isc__app_finish
+#define isc_app_block isc__app_block
+#define isc_app_unblock isc__app_unblock
+#define isc_appctx_create isc__appctx_create
+#define isc_appctx_destroy isc__appctx_destroy
+#define isc_appctx_settaskmgr isc__appctx_settaskmgr
+#define isc_appctx_setsocketmgr isc__appctx_setsocketmgr
+#define isc_appctx_settimermgr isc__appctx_settimermgr
+
+#define isc_mem_checkdestroyed isc__mem_checkdestroyed
+#define isc_mem_createx isc__mem_createx
+#define isc_mem_createx2 isc__mem_createx2
+#define isc_mem_create isc__mem_create
+#define isc_mem_create2 isc__mem_create2
+#define isc_mem_attach isc__mem_attach
+#define isc_mem_detach isc__mem_detach
+#define isc__mem_putanddetach isc___mem_putanddetach
+#define isc_mem_destroy isc__mem_destroy
+#define isc_mem_ondestroy isc__mem_ondestroy
+#define isc__mem_get isc___mem_get
+#define isc__mem_put isc___mem_put
+#define isc_mem_stats isc__mem_stats
+#define isc__mem_allocate isc___mem_allocate
+#define isc__mem_free isc___mem_free
+#define isc__mem_strdup isc___mem_strdup
+#define isc__mem_reallocate isc___mem_reallocate
+#define isc_mem_references isc__mem_references
+#define isc_mem_setdestroycheck isc__mem_setdestroycheck
+#define isc_mem_setquota isc__mem_setquota
+#define isc_mem_getname isc__mem_getname
+#define isc_mem_getquota isc__mem_getquota
+#define isc_mem_gettag isc__mem_gettag
+#define isc_mem_inuse isc__mem_inuse
+#define isc_mem_isovermem isc__mem_isovermem
+#define isc_mem_setname isc__mem_setname
+#define isc_mem_setwater isc__mem_setwater
+#define isc_mem_printallactive isc__mem_printallactive
+#define isc_mem_waterack isc__mem_waterack
+#define isc_mempool_create isc__mempool_create
+#define isc_mempool_setname isc__mempool_setname
+#define isc_mempool_destroy isc__mempool_destroy
+#define isc_mempool_associatelock isc__mempool_associatelock
+#define isc__mempool_get isc___mempool_get
+#define isc__mempool_put isc___mempool_put
+#define isc_mempool_setfreemax isc__mempool_setfreemax
+#define isc_mempool_getfreemax isc__mempool_getfreemax
+#define isc_mempool_getfreecount isc__mempool_getfreecount
+#define isc_mempool_setmaxalloc isc__mempool_setmaxalloc
+#define isc_mempool_getmaxalloc isc__mempool_getmaxalloc
+#define isc_mempool_getallocated isc__mempool_getallocated
+#define isc_mempool_setfillcount isc__mempool_setfillcount
+#define isc_mempool_getfillcount isc__mempool_getfillcount
+
+#define isc_socket_create isc__socket_create
+#define isc_socket_dup isc__socket_dup
+#define isc_socket_attach isc__socket_attach
+#define isc_socket_detach isc__socket_detach
+#define isc_socketmgr_create isc__socketmgr_create
+#define isc_socketmgr_create2 isc__socketmgr_create2
+#define isc_socketmgr_destroy isc__socketmgr_destroy
+#define isc_socket_open isc__socket_open
+#define isc_socket_close isc__socket_close
+#define isc_socket_recvv isc__socket_recvv
+#define isc_socket_recv isc__socket_recv
+#define isc_socket_recv2 isc__socket_recv2
+#define isc_socket_send isc__socket_send
+#define isc_socket_sendto isc__socket_sendto
+#define isc_socket_sendv isc__socket_sendv
+#define isc_socket_sendtov isc__socket_sendtov
+#define isc_socket_sendto2 isc__socket_sendto2
+#define isc_socket_cleanunix isc__socket_cleanunix
+#define isc_socket_permunix isc__socket_permunix
+#define isc_socket_bind isc__socket_bind
+#define isc_socket_filter isc__socket_filter
+#define isc_socket_listen isc__socket_listen
+#define isc_socket_accept isc__socket_accept
+#define isc_socket_connect isc__socket_connect
+#define isc_socket_getfd isc__socket_getfd
+#define isc_socket_getname isc__socket_getname
+#define isc_socket_gettag isc__socket_gettag
+#define isc_socket_getpeername isc__socket_getpeername
+#define isc_socket_getsockname isc__socket_getsockname
+#define isc_socket_cancel isc__socket_cancel
+#define isc_socket_gettype isc__socket_gettype
+#define isc_socket_isbound isc__socket_isbound
+#define isc_socket_ipv6only isc__socket_ipv6only
+#define isc_socket_setname isc__socket_setname
+#define isc_socketmgr_getmaxsockets isc__socketmgr_getmaxsockets
+#define isc_socketmgr_setstats isc__socketmgr_setstats
+#define isc_socketmgr_setreserved isc__socketmgr_setreserved
+#define isc__socketmgr_maxudp isc___socketmgr_maxudp
+#define isc_socket_fdwatchcreate isc__socket_fdwatchcreate
+#define isc_socket_fdwatchpoke isc__socket_fdwatchpoke
+
+#define isc_task_create isc__task_create
+#define isc_task_attach isc__task_attach
+#define isc_task_detach isc__task_detach
+/* #define isc_task_exiting isc__task_exiting XXXMPA */
+#define isc_task_send isc__task_send
+#define isc_task_sendanddetach isc__task_sendanddetach
+#define isc_task_purgerange isc__task_purgerange
+#define isc_task_purge isc__task_purge
+#define isc_task_purgeevent isc__task_purgeevent
+#define isc_task_unsendrange isc__task_unsendrange
+#define isc_task_unsend isc__task_unsend
+#define isc_task_onshutdown isc__task_onshutdown
+#define isc_task_shutdown isc__task_shutdown
+#define isc_task_destroy isc__task_destroy
+#define isc_task_setname isc__task_setname
+#define isc_task_getname isc__task_getname
+#define isc_task_gettag isc__task_gettag
+#define isc_task_getcurrenttime isc__task_getcurrenttime
+#define isc_taskmgr_create isc__taskmgr_create
+#define isc_taskmgr_setmode isc__taskmgr_setmode
+#define isc_taskmgr_mode isc__taskmgr_mode
+#define isc_taskmgr_destroy isc__taskmgr_destroy
+#define isc_task_beginexclusive isc__task_beginexclusive
+#define isc_task_endexclusive isc__task_endexclusive
+#define isc_task_setprivilege isc__task_setprivilege
+#define isc_task_privilege isc__task_privilege
+
+#define isc_timer_create isc__timer_create
+#define isc_timer_reset isc__timer_reset
+#define isc_timer_gettype isc__timer_gettype
+#define isc_timer_touch isc__timer_touch
+#define isc_timer_attach isc__timer_attach
+#define isc_timer_detach isc__timer_detach
+#define isc_timermgr_create isc__timermgr_create
+#define isc_timermgr_poke isc__timermgr_poke
+#define isc_timermgr_destroy isc__timermgr_destroy
+
+#endif /* BIND9 */
+
+#endif /* ISCAPI_NAMESPACE_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/netaddr.h b/contrib/ntp/libntp/lib/isc/include/isc/netaddr.h
new file mode 100644
index 000000000000..954d77019b69
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/netaddr.h
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: netaddr.h,v 1.37 2009/01/17 23:47:43 tbox Exp $ */
+
+#ifndef ISC_NETADDR_H
+#define ISC_NETADDR_H 1
+
+/*! \file isc/netaddr.h */
+
+#include <isc/lang.h>
+#include <isc/net.h>
+#include <isc/types.h>
+
+#ifdef ISC_PLATFORM_HAVESYSUNH
+#include <sys/types.h>
+#include <sys/un.h>
+#endif
+
+ISC_LANG_BEGINDECLS
+
+struct isc_netaddr {
+ unsigned int family;
+ union {
+ struct in_addr in;
+ struct in6_addr in6;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ char un[sizeof(((struct sockaddr_un *)0)->sun_path)];
+#endif
+ } type;
+ isc_uint32_t zone;
+};
+
+isc_boolean_t
+isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b);
+
+/*%<
+ * Compare network addresses 'a' and 'b'. Return #ISC_TRUE if
+ * they are equal, #ISC_FALSE if not.
+ */
+
+isc_boolean_t
+isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b,
+ unsigned int prefixlen);
+/*%<
+ * Compare the 'prefixlen' most significant bits of the network
+ * addresses 'a' and 'b'. If 'b''s scope is zero then 'a''s scope is
+ * ignored. Return #ISC_TRUE if they are equal, #ISC_FALSE if not.
+ */
+
+isc_result_t
+isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp);
+/*%<
+ * Convert a netmask in 's' into a prefix length in '*lenp'.
+ * The mask should consist of zero or more '1' bits in the most
+ * most significant part of the address, followed by '0' bits.
+ * If this is not the case, #ISC_R_MASKNONCONTIG is returned.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_MASKNONCONTIG
+ */
+
+isc_result_t
+isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target);
+/*%<
+ * Append a text representation of 'sockaddr' to the buffer 'target'.
+ * The text is NOT null terminated. Handles IPv4 and IPv6 addresses.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOSPACE The text or the null termination did not fit.
+ *\li #ISC_R_FAILURE Unspecified failure
+ */
+
+void
+isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size);
+/*%<
+ * Format a human-readable representation of the network address '*na'
+ * into the character array 'array', which is of size 'size'.
+ * The resulting string is guaranteed to be null-terminated.
+ */
+
+#define ISC_NETADDR_FORMATSIZE \
+ sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS")
+/*%<
+ * Minimum size of array to pass to isc_netaddr_format().
+ */
+
+void
+isc_netaddr_fromsockaddr(isc_netaddr_t *netaddr, const isc_sockaddr_t *source);
+
+void
+isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina);
+
+void
+isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6);
+
+isc_result_t
+isc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path);
+
+void
+isc_netaddr_setzone(isc_netaddr_t *netaddr, isc_uint32_t zone);
+
+isc_uint32_t
+isc_netaddr_getzone(const isc_netaddr_t *netaddr);
+
+void
+isc_netaddr_any(isc_netaddr_t *netaddr);
+/*%<
+ * Return the IPv4 wildcard address.
+ */
+
+void
+isc_netaddr_any6(isc_netaddr_t *netaddr);
+/*%<
+ * Return the IPv6 wildcard address.
+ */
+
+isc_boolean_t
+isc_netaddr_ismulticast(isc_netaddr_t *na);
+/*%<
+ * Returns ISC_TRUE if the address is a multicast address.
+ */
+
+isc_boolean_t
+isc_netaddr_isexperimental(isc_netaddr_t *na);
+/*%<
+ * Returns ISC_TRUE if the address is a experimental (CLASS E) address.
+ */
+
+isc_boolean_t
+isc_netaddr_islinklocal(isc_netaddr_t *na);
+/*%<
+ * Returns #ISC_TRUE if the address is a link local address.
+ */
+
+isc_boolean_t
+isc_netaddr_issitelocal(isc_netaddr_t *na);
+/*%<
+ * Returns #ISC_TRUE if the address is a site local address.
+ */
+
+void
+isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s);
+/*%<
+ * Convert an IPv6 v4mapped address into an IPv4 address.
+ */
+
+isc_result_t
+isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen);
+/*
+ * Test whether the netaddr 'na' and 'prefixlen' are consistant.
+ * e.g. prefixlen within range.
+ * na does not have bits set which are not covered by the prefixlen.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * ISC_R_RANGE prefixlen out of range
+ * ISC_R_NOTIMPLEMENTED unsupported family
+ * ISC_R_FAILURE extra bits.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NETADDR_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/netscope.h b/contrib/ntp/libntp/lib/isc/include/isc/netscope.h
new file mode 100644
index 000000000000..163a08ca2ea7
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/netscope.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: netscope.h,v 1.13 2009/06/25 23:48:02 tbox Exp $ */
+
+#ifndef ISC_NETSCOPE_H
+#define ISC_NETSCOPE_H 1
+
+/*! \file isc/netscope.h */
+
+ISC_LANG_BEGINDECLS
+
+/*%
+ * Convert a string of an IPv6 scope zone to zone index. If the conversion
+ * succeeds, 'zoneid' will store the index value.
+ *
+ * XXXJT: when a standard interface for this purpose is defined,
+ * we should use it.
+ *
+ * Returns:
+ * \li ISC_R_SUCCESS: conversion succeeds
+ * \li ISC_R_FAILURE: conversion fails
+ */
+isc_result_t
+isc_netscope_pton(int af, char *scopename, void *addr, isc_uint32_t *zoneid);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NETSCOPE_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/ondestroy.h b/contrib/ntp/libntp/lib/isc/include/isc/ondestroy.h
new file mode 100644
index 000000000000..64bd64333707
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/ondestroy.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ondestroy.h,v 1.14 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_ONDESTROY_H
+#define ISC_ONDESTROY_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*! \file isc/ondestroy.h
+ * ondestroy handling.
+ *
+ * Any class ``X'' of objects that wants to send out notifications
+ * on its destruction should declare a field of type isc_ondestroy_t
+ * (call it 'ondest').
+ *
+ * \code
+ * typedef struct {
+ * ...
+ * isc_ondestroy_t ondest;
+ * ...
+ * } X;
+ * \endcode
+ *
+ * When an object ``A'' of type X is created
+ * it must initialize the field ondest with a call to
+ *
+ * \code
+ * isc_ondestroy_init(&A->ondest).
+ * \endcode
+ *
+ * X should also provide a registration function for third-party
+ * objects to call to register their interest in being told about
+ * the destruction of a particular instance of X.
+ *
+ * \code
+ * isc_result_t
+ * X_ondestroy(X *instance, isc_task_t *task,
+ * isc_event_t **eventp) {
+ * return(isc_ondestroy_register(&instance->ondest, task,eventp));
+ * }
+ * \endcode
+ *
+ * Note: locking of the ondestory structure embedded inside of X, is
+ * X's responsibility.
+ *
+ * When an instance of X is destroyed, a call to isc_ondestroy_notify()
+ * sends the notifications:
+ *
+ * \code
+ * X *instance;
+ * isc_ondestroy_t ondest = instance->ondest;
+ *
+ * ... completely cleanup 'instance' here...
+ *
+ * isc_ondestroy_notify(&ondest, instance);
+ * \endcode
+ *
+ *
+ * see lib/dns/zone.c for an ifdef'd-out example.
+ */
+
+struct isc_ondestroy {
+ unsigned int magic;
+ isc_eventlist_t events;
+};
+
+void
+isc_ondestroy_init(isc_ondestroy_t *ondest);
+/*%<
+ * Initialize the on ondest structure. *must* be called before first call
+ * to isc_ondestroy_register().
+ */
+
+isc_result_t
+isc_ondestroy_register(isc_ondestroy_t *ondest, isc_task_t *task,
+ isc_event_t **eventp);
+
+/*%<
+ * Stores task and *eventp away inside *ondest. Ownership of **event is
+ * taken from the caller (and *eventp is set to NULL). The task is attached
+ * to.
+ */
+
+void
+isc_ondestroy_notify(isc_ondestroy_t *ondest, void *sender);
+/*%<
+ * Dispatches the event(s) to the task(s) that were given in
+ * isc_ondestroy_register call(s) (done via calls to
+ * isc_task_sendanddetach()). Before dispatch, the sender value of each
+ * event structure is set to the value of the sender paramater. The
+ * internal structures of the ondest parameter are cleaned out, so no other
+ * cleanup is needed.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ONDESTROY_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/platform.h b/contrib/ntp/libntp/lib/isc/include/isc/platform.h
new file mode 100644
index 000000000000..bd11a25503a5
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/platform.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
+ * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
+ * INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
+ * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
+ * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
+ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: platform.h.in,v 1.28 2001/11/19 03:08:26 mayer Exp $ */
+
+#ifndef ISC_PLATFORM_H
+#define ISC_PLATFORM_H 1
+
+
+#ifndef ISC_PLATFORM_USEDECLSPEC
+#define LIBISC_EXTERNAL_DATA
+#define LIBDNS_EXTERNAL_DATA
+#define LIBISCCC_EXTERNAL_DATA
+#define LIBISCCFG_EXTERNAL_DATA
+#define LIBBIND9_EXTERNAL_DATA
+#endif /* ISC_PLATFORM_USEDECLSPEC */
+
+/*
+ * Tell emacs to use C mode for this file.
+ *
+ * Local Variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* ISC_PLATFORM_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/print.h b/contrib/ntp/libntp/lib/isc/include/isc/print.h
new file mode 100644
index 000000000000..cd1e38eaf6fb
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/print.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: print.h,v 1.26 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_PRINT_H
+#define ISC_PRINT_H 1
+
+/*! \file isc/print.h */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/formatcheck.h> /* Required for ISC_FORMAT_PRINTF() macro. */
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+/*!
+ * This block allows lib/isc/print.c to be cleanly compiled even if
+ * the platform does not need it. The standard Makefile will still
+ * not compile print.c or archive print.o, so this is just to make test
+ * compilation ("make print.o") easier.
+ */
+#if !defined(ISC_PLATFORM_NEEDVSNPRINTF) && defined(ISC__PRINT_SOURCE)
+#define ISC_PLATFORM_NEEDVSNPRINTF
+#endif
+
+#if !defined(ISC_PLATFORM_NEEDSPRINTF) && defined(ISC__PRINT_SOURCE)
+#define ISC_PLATFORM_NEEDSPRINTF
+#endif
+
+/***
+ *** Macros
+ ***/
+#define ISC_PRINT_QUADFORMAT ISC_PLATFORM_QUADFORMAT
+
+/***
+ *** Functions
+ ***/
+
+#ifdef ISC_PLATFORM_NEEDVSNPRINTF
+#include <stdarg.h>
+#include <stddef.h>
+#endif
+#ifdef ISC_PLATFORM_NEEDSPRINTF
+#include <stdio.h>
+#endif
+
+
+ISC_LANG_BEGINDECLS
+
+#ifdef ISC_PLATFORM_NEEDVSNPRINTF
+int
+isc_print_vsnprintf(char *str, size_t size, const char *format, va_list ap)
+ ISC_FORMAT_PRINTF(3, 0);
+#define vsnprintf isc_print_vsnprintf
+
+int
+isc_print_snprintf(char *str, size_t size, const char *format, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+#define snprintf isc_print_snprintf
+#endif /* ISC_PLATFORM_NEEDVSNPRINTF */
+
+#ifdef ISC_PLATFORM_NEEDSPRINTF
+int
+isc_print_sprintf(char *str, const char *format, ...) ISC_FORMAT_PRINTF(2, 3);
+#define sprintf isc_print_sprintf
+#endif
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_PRINT_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/random.h b/contrib/ntp/libntp/lib/isc/include/isc/random.h
new file mode 100644
index 000000000000..1f9572d30ebf
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/random.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: random.h,v 1.20 2009/01/17 23:47:43 tbox Exp $ */
+
+#ifndef ISC_RANDOM_H
+#define ISC_RANDOM_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*! \file isc/random.h
+ * \brief Implements a random state pool which will let the caller return a
+ * series of possibly non-reproducible random values.
+ *
+ * Note that the
+ * strength of these numbers is not all that high, and should not be
+ * used in cryptography functions. It is useful for jittering values
+ * a bit here and there, such as timeouts, etc.
+ */
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_random_seed(isc_uint32_t seed);
+/*%<
+ * Set the initial seed of the random state.
+ */
+
+void
+isc_random_get(isc_uint32_t *val);
+/*%<
+ * Get a random value.
+ *
+ * Requires:
+ * val != NULL.
+ */
+
+isc_uint32_t
+isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter);
+/*%<
+ * Get a random value between (max - jitter) and (max).
+ * This is useful for jittering timer values.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RANDOM_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/region.h b/contrib/ntp/libntp/lib/isc/include/isc/region.h
new file mode 100644
index 000000000000..43d8f8f2d3e9
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/region.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: region.h,v 1.25 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_REGION_H
+#define ISC_REGION_H 1
+
+/*! \file isc/region.h */
+
+#include <isc/types.h>
+
+struct isc_region {
+ unsigned char * base;
+ unsigned int length;
+};
+
+struct isc_textregion {
+ char * base;
+ unsigned int length;
+};
+
+/* XXXDCL questionable ... bears discussion. we have been putting off
+ * discussing the region api.
+ */
+struct isc_constregion {
+ const void * base;
+ unsigned int length;
+};
+
+struct isc_consttextregion {
+ const char * base;
+ unsigned int length;
+};
+
+/*@{*/
+/*!
+ * The region structure is not opaque, and is usually directly manipulated.
+ * Some macros are defined below for convenience.
+ */
+
+#define isc_region_consume(r,l) \
+ do { \
+ isc_region_t *_r = (r); \
+ unsigned int _l = (l); \
+ INSIST(_r->length >= _l); \
+ _r->base += _l; \
+ _r->length -= _l; \
+ } while (0)
+
+#define isc_textregion_consume(r,l) \
+ do { \
+ isc_textregion_t *_r = (r); \
+ unsigned int _l = (l); \
+ INSIST(_r->length >= _l); \
+ _r->base += _l; \
+ _r->length -= _l; \
+ } while (0)
+
+#define isc_constregion_consume(r,l) \
+ do { \
+ isc_constregion_t *_r = (r); \
+ unsigned int _l = (l); \
+ INSIST(_r->length >= _l); \
+ _r->base += _l; \
+ _r->length -= _l; \
+ } while (0)
+/*@}*/
+
+int
+isc_region_compare(isc_region_t *r1, isc_region_t *r2);
+/*%<
+ * Compares the contents of two regions
+ *
+ * Requires:
+ *\li 'r1' is a valid region
+ *\li 'r2' is a valid region
+ *
+ * Returns:
+ *\li < 0 if r1 is lexicographically less than r2
+ *\li = 0 if r1 is lexicographically identical to r2
+ *\li > 0 if r1 is lexicographically greater than r2
+ */
+
+#endif /* ISC_REGION_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/result.h b/contrib/ntp/libntp/lib/isc/include/isc/result.h
new file mode 100644
index 000000000000..dcd457b3d1b0
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/result.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_RESULT_H
+#define ISC_RESULT_H 1
+
+/*! \file isc/result.h */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#define ISC_R_SUCCESS 0 /*%< success */
+#define ISC_R_NOMEMORY 1 /*%< out of memory */
+#define ISC_R_TIMEDOUT 2 /*%< timed out */
+#define ISC_R_NOTHREADS 3 /*%< no available threads */
+#define ISC_R_ADDRNOTAVAIL 4 /*%< address not available */
+#define ISC_R_ADDRINUSE 5 /*%< address in use */
+#define ISC_R_NOPERM 6 /*%< permission denied */
+#define ISC_R_NOCONN 7 /*%< no pending connections */
+#define ISC_R_NETUNREACH 8 /*%< network unreachable */
+#define ISC_R_HOSTUNREACH 9 /*%< host unreachable */
+#define ISC_R_NETDOWN 10 /*%< network down */
+#define ISC_R_HOSTDOWN 11 /*%< host down */
+#define ISC_R_CONNREFUSED 12 /*%< connection refused */
+#define ISC_R_NORESOURCES 13 /*%< not enough free resources */
+#define ISC_R_EOF 14 /*%< end of file */
+#define ISC_R_BOUND 15 /*%< socket already bound */
+#define ISC_R_RELOAD 16 /*%< reload */
+#define ISC_R_SUSPEND ISC_R_RELOAD /*%< alias of 'reload' */
+#define ISC_R_LOCKBUSY 17 /*%< lock busy */
+#define ISC_R_EXISTS 18 /*%< already exists */
+#define ISC_R_NOSPACE 19 /*%< ran out of space */
+#define ISC_R_CANCELED 20 /*%< operation canceled */
+#define ISC_R_NOTBOUND 21 /*%< socket is not bound */
+#define ISC_R_SHUTTINGDOWN 22 /*%< shutting down */
+#define ISC_R_NOTFOUND 23 /*%< not found */
+#define ISC_R_UNEXPECTEDEND 24 /*%< unexpected end of input */
+#define ISC_R_FAILURE 25 /*%< generic failure */
+#define ISC_R_IOERROR 26 /*%< I/O error */
+#define ISC_R_NOTIMPLEMENTED 27 /*%< not implemented */
+#define ISC_R_UNBALANCED 28 /*%< unbalanced parentheses */
+#define ISC_R_NOMORE 29 /*%< no more */
+#define ISC_R_INVALIDFILE 30 /*%< invalid file */
+#define ISC_R_BADBASE64 31 /*%< bad base64 encoding */
+#define ISC_R_UNEXPECTEDTOKEN 32 /*%< unexpected token */
+#define ISC_R_QUOTA 33 /*%< quota reached */
+#define ISC_R_UNEXPECTED 34 /*%< unexpected error */
+#define ISC_R_ALREADYRUNNING 35 /*%< already running */
+#define ISC_R_IGNORE 36 /*%< ignore */
+#define ISC_R_MASKNONCONTIG 37 /*%< addr mask not contiguous */
+#define ISC_R_FILENOTFOUND 38 /*%< file not found */
+#define ISC_R_FILEEXISTS 39 /*%< file already exists */
+#define ISC_R_NOTCONNECTED 40 /*%< socket is not connected */
+#define ISC_R_RANGE 41 /*%< out of range */
+#define ISC_R_NOENTROPY 42 /*%< out of entropy */
+#define ISC_R_MULTICAST 43 /*%< invalid use of multicast */
+#define ISC_R_NOTFILE 44 /*%< not a file */
+#define ISC_R_NOTDIRECTORY 45 /*%< not a directory */
+#define ISC_R_QUEUEFULL 46 /*%< queue is full */
+#define ISC_R_FAMILYMISMATCH 47 /*%< address family mismatch */
+#define ISC_R_FAMILYNOSUPPORT 48 /*%< AF not supported */
+#define ISC_R_BADHEX 49 /*%< bad hex encoding */
+#define ISC_R_TOOMANYOPENFILES 50 /*%< too many open files */
+#define ISC_R_NOTBLOCKING 51 /*%< not blocking */
+#define ISC_R_UNBALANCEDQUOTES 52 /*%< unbalanced quotes */
+#define ISC_R_INPROGRESS 53 /*%< operation in progress */
+#define ISC_R_CONNECTIONRESET 54 /*%< connection reset */
+#define ISC_R_SOFTQUOTA 55 /*%< soft quota reached */
+#define ISC_R_BADNUMBER 56 /*%< not a valid number */
+#define ISC_R_DISABLED 57 /*%< disabled */
+#define ISC_R_MAXSIZE 58 /*%< max size */
+#define ISC_R_BADADDRESSFORM 59 /*%< invalid address format */
+#define ISC_R_BADBASE32 60 /*%< bad base32 encoding */
+#define ISC_R_UNSET 61 /*%< unset */
+
+/*% Not a result code: the number of results. */
+#define ISC_R_NRESULTS 62
+
+ISC_LANG_BEGINDECLS
+
+const char *
+isc_result_totext(isc_result_t);
+/*%<
+ * Convert an isc_result_t into a string message describing the result.
+ */
+
+isc_result_t
+isc_result_register(unsigned int base, unsigned int nresults,
+ const char **text, isc_msgcat_t *msgcat, int set);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RESULT_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/resultclass.h b/contrib/ntp/libntp/lib/isc/include/isc/resultclass.h
new file mode 100644
index 000000000000..d91e800e063c
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/resultclass.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: resultclass.h,v 1.20 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISC_RESULTCLASS_H
+#define ISC_RESULTCLASS_H 1
+
+
+/*! \file isc/resultclass.h
+ * \brief Registry of Predefined Result Type Classes
+ *
+ * A result class number is an unsigned 16 bit number. Each class may
+ * contain up to 65536 results. A result code is formed by adding the
+ * result number within the class to the class number multiplied by 65536.
+ *
+ * Classes < 1024 are reserved for ISC use.
+ * Result classes >= 1024 and <= 65535 are reserved for application use.
+ */
+
+#define ISC_RESULTCLASS_FROMNUM(num) ((num) << 16)
+#define ISC_RESULTCLASS_TONUM(rclass) ((rclass) >> 16)
+#define ISC_RESULTCLASS_SIZE 65536
+#define ISC_RESULTCLASS_INCLASS(rclass, result) \
+ ((rclass) == ((result) & 0xFFFF0000))
+
+
+#define ISC_RESULTCLASS_ISC ISC_RESULTCLASS_FROMNUM(0)
+#define ISC_RESULTCLASS_DNS ISC_RESULTCLASS_FROMNUM(1)
+#define ISC_RESULTCLASS_DST ISC_RESULTCLASS_FROMNUM(2)
+#define ISC_RESULTCLASS_DNSRCODE ISC_RESULTCLASS_FROMNUM(3)
+#define ISC_RESULTCLASS_OMAPI ISC_RESULTCLASS_FROMNUM(4)
+#define ISC_RESULTCLASS_ISCCC ISC_RESULTCLASS_FROMNUM(5)
+#define ISC_RESULTCLASS_DHCP ISC_RESULTCLASS_FROMNUM(6)
+
+
+#endif /* ISC_RESULTCLASS_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/sha1.h b/contrib/ntp/libntp/lib/isc/include/isc/sha1.h
new file mode 100644
index 000000000000..313ff96391b2
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/sha1.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef ISC_SHA1_H
+#define ISC_SHA1_H 1
+
+/* $Id: sha1.h,v 1.19 2009/02/06 23:47:42 tbox Exp $ */
+
+/* $NetBSD: sha1.h,v 1.2 1998/05/29 22:55:44 thorpej Exp $ */
+
+/*! \file isc/sha1.h
+ * \brief SHA-1 in C
+ * \author By Steve Reid <steve@edmweb.com>
+ * \note 100% Public Domain
+ */
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#define ISC_SHA1_DIGESTLENGTH 20U
+#define ISC_SHA1_BLOCK_LENGTH 64U
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+#include <openssl/evp.h>
+
+typedef EVP_MD_CTX isc_sha1_t;
+
+#else
+
+typedef struct {
+ isc_uint32_t state[5];
+ isc_uint32_t count[2];
+ unsigned char buffer[ISC_SHA1_BLOCK_LENGTH];
+} isc_sha1_t;
+#endif
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_sha1_init(isc_sha1_t *ctx);
+
+void
+isc_sha1_invalidate(isc_sha1_t *ctx);
+
+void
+isc_sha1_update(isc_sha1_t *ctx, const unsigned char *data, unsigned int len);
+
+void
+isc_sha1_final(isc_sha1_t *ctx, unsigned char *digest);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SHA1_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/sockaddr.h b/contrib/ntp/libntp/lib/isc/include/isc/sockaddr.h
new file mode 100644
index 000000000000..1e6914222c1b
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/sockaddr.h
@@ -0,0 +1,241 @@
+/*
+ * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: sockaddr.h,v 1.57 2009/01/18 23:48:14 tbox Exp $ */
+
+#ifndef ISC_SOCKADDR_H
+#define ISC_SOCKADDR_H 1
+
+/*! \file isc/sockaddr.h */
+
+#include <isc/lang.h>
+#include <isc/net.h>
+#include <isc/types.h>
+#ifdef ISC_PLATFORM_HAVESYSUNH
+#include <sys/un.h>
+#endif
+
+struct isc_sockaddr {
+ union {
+ struct sockaddr sa;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ struct sockaddr_un sunix;
+#endif
+ } type;
+ unsigned int length; /* XXXRTH beginning? */
+ ISC_LINK(struct isc_sockaddr) link;
+};
+
+typedef ISC_LIST(struct isc_sockaddr) isc_sockaddrlist_t;
+
+#define ISC_SOCKADDR_CMPADDR 0x0001 /*%< compare the address
+ * sin_addr/sin6_addr */
+#define ISC_SOCKADDR_CMPPORT 0x0002 /*%< compare the port
+ * sin_port/sin6_port */
+#define ISC_SOCKADDR_CMPSCOPE 0x0004 /*%< compare the scope
+ * sin6_scope */
+#define ISC_SOCKADDR_CMPSCOPEZERO 0x0008 /*%< when comparing scopes
+ * zero scopes always match */
+
+ISC_LANG_BEGINDECLS
+
+isc_boolean_t
+isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int flags);
+/*%<
+ * Compare the elements of the two address ('a' and 'b') as specified
+ * by 'flags' and report if they are equal or not.
+ *
+ * 'flags' is set from ISC_SOCKADDR_CMP*.
+ */
+
+isc_boolean_t
+isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b);
+/*%<
+ * Return ISC_TRUE iff the socket addresses 'a' and 'b' are equal.
+ */
+
+isc_boolean_t
+isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b);
+/*%<
+ * Return ISC_TRUE iff the address parts of the socket addresses
+ * 'a' and 'b' are equal, ignoring the ports.
+ */
+
+isc_boolean_t
+isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int prefixlen);
+/*%<
+ * Return ISC_TRUE iff the most significant 'prefixlen' bits of the
+ * socket addresses 'a' and 'b' are equal, ignoring the ports.
+ * If 'b''s scope is zero then 'a''s scope will be ignored.
+ */
+
+unsigned int
+isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only);
+/*%<
+ * Return a hash value for the socket address 'sockaddr'. If 'address_only'
+ * is ISC_TRUE, the hash value will not depend on the port.
+ *
+ * IPv6 addresses containing mapped IPv4 addresses generate the same hash
+ * value as the equivalent IPv4 address.
+ */
+
+void
+isc_sockaddr_any(isc_sockaddr_t *sockaddr);
+/*%<
+ * Return the IPv4 wildcard address.
+ */
+
+void
+isc_sockaddr_any6(isc_sockaddr_t *sockaddr);
+/*%<
+ * Return the IPv6 wildcard address.
+ */
+
+void
+isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int family);
+/*%<
+ * Set '*sockaddr' to the wildcard address of protocol family
+ * 'family'.
+ *
+ * Requires:
+ * \li 'family' is AF_INET or AF_INET6.
+ */
+
+void
+isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
+ in_port_t port);
+/*%<
+ * Construct an isc_sockaddr_t from an IPv4 address and port.
+ */
+
+void
+isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6,
+ in_port_t port);
+/*%<
+ * Construct an isc_sockaddr_t from an IPv6 address and port.
+ */
+
+void
+isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
+ in_port_t port);
+/*%<
+ * Construct an IPv6 isc_sockaddr_t representing a mapped IPv4 address.
+ */
+
+void
+isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
+ in_port_t port);
+/*%<
+ * Construct an isc_sockaddr_t from an isc_netaddr_t and port.
+ */
+
+int
+isc_sockaddr_pf(const isc_sockaddr_t *sockaddr);
+/*%<
+ * Get the protocol family of 'sockaddr'.
+ *
+ * Requires:
+ *
+ *\li 'sockaddr' is a valid sockaddr with an address family of AF_INET
+ * or AF_INET6.
+ *
+ * Returns:
+ *
+ *\li The protocol family of 'sockaddr', e.g. PF_INET or PF_INET6.
+ */
+
+void
+isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port);
+/*%<
+ * Set the port of 'sockaddr' to 'port'.
+ */
+
+in_port_t
+isc_sockaddr_getport(const isc_sockaddr_t *sockaddr);
+/*%<
+ * Get the port stored in 'sockaddr'.
+ */
+
+isc_result_t
+isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target);
+/*%<
+ * Append a text representation of 'sockaddr' to the buffer 'target'.
+ * The text will include both the IP address (v4 or v6) and the port.
+ * The text is null terminated, but the terminating null is not
+ * part of the buffer's used region.
+ *
+ * Returns:
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOSPACE The text or the null termination did not fit.
+ */
+
+void
+isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size);
+/*%<
+ * Format a human-readable representation of the socket address '*sa'
+ * into the character array 'array', which is of size 'size'.
+ * The resulting string is guaranteed to be null-terminated.
+ */
+
+isc_boolean_t
+isc_sockaddr_ismulticast(const isc_sockaddr_t *sa);
+/*%<
+ * Returns #ISC_TRUE if the address is a multicast address.
+ */
+
+isc_boolean_t
+isc_sockaddr_isexperimental(const isc_sockaddr_t *sa);
+/*
+ * Returns ISC_TRUE if the address is a experimental (CLASS E) address.
+ */
+
+isc_boolean_t
+isc_sockaddr_islinklocal(const isc_sockaddr_t *sa);
+/*%<
+ * Returns ISC_TRUE if the address is a link local address.
+ */
+
+isc_boolean_t
+isc_sockaddr_issitelocal(const isc_sockaddr_t *sa);
+/*%<
+ * Returns ISC_TRUE if the address is a sitelocal address.
+ */
+
+isc_result_t
+isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path);
+/*
+ * Create a UNIX domain sockaddr that refers to path.
+ *
+ * Returns:
+ * \li ISC_R_NOSPACE
+ * \li ISC_R_NOTIMPLEMENTED
+ * \li ISC_R_SUCCESS
+ */
+
+#define ISC_SOCKADDR_FORMATSIZE \
+ sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:XXX.XXX.XXX.XXX%SSSSSSSSSS#YYYYY")
+/*%<
+ * Minimum size of array to pass to isc_sockaddr_format().
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SOCKADDR_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/socket.h b/contrib/ntp/libntp/lib/isc/include/isc/socket.h
new file mode 100644
index 000000000000..46e05a077492
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/socket.h
@@ -0,0 +1,1168 @@
+/*
+ * Copyright (C) 2004-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_SOCKET_H
+#define ISC_SOCKET_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/socket.h
+ * \brief Provides TCP and UDP sockets for network I/O. The sockets are event
+ * sources in the task system.
+ *
+ * When I/O completes, a completion event for the socket is posted to the
+ * event queue of the task which requested the I/O.
+ *
+ * \li MP:
+ * The module ensures appropriate synchronization of data structures it
+ * creates and manipulates.
+ * Clients of this module must not be holding a socket's task's lock when
+ * making a call that affects that socket. Failure to follow this rule
+ * can result in deadlock.
+ * The caller must ensure that isc_socketmgr_destroy() is called only
+ * once for a given manager.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+#include <isc/event.h>
+#include <isc/eventclass.h>
+#include <isc/time.h>
+#include <isc/region.h>
+#include <isc/sockaddr.h>
+#include <isc/xml.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Constants
+ ***/
+
+/*%
+ * Maximum number of buffers in a scatter/gather read/write. The operating
+ * system in use must support at least this number (plus one on some.)
+ */
+#define ISC_SOCKET_MAXSCATTERGATHER 8
+
+/*%
+ * In isc_socket_bind() set socket option SO_REUSEADDR prior to calling
+ * bind() if a non zero port is specified (AF_INET and AF_INET6).
+ */
+#define ISC_SOCKET_REUSEADDRESS 0x01U
+
+/*%
+ * Statistics counters. Used as isc_statscounter_t values.
+ */
+enum {
+ isc_sockstatscounter_udp4open = 0,
+ isc_sockstatscounter_udp6open = 1,
+ isc_sockstatscounter_tcp4open = 2,
+ isc_sockstatscounter_tcp6open = 3,
+ isc_sockstatscounter_unixopen = 4,
+
+ isc_sockstatscounter_udp4openfail = 5,
+ isc_sockstatscounter_udp6openfail = 6,
+ isc_sockstatscounter_tcp4openfail = 7,
+ isc_sockstatscounter_tcp6openfail = 8,
+ isc_sockstatscounter_unixopenfail = 9,
+
+ isc_sockstatscounter_udp4close = 10,
+ isc_sockstatscounter_udp6close = 11,
+ isc_sockstatscounter_tcp4close = 12,
+ isc_sockstatscounter_tcp6close = 13,
+ isc_sockstatscounter_unixclose = 14,
+ isc_sockstatscounter_fdwatchclose = 15,
+
+ isc_sockstatscounter_udp4bindfail = 16,
+ isc_sockstatscounter_udp6bindfail = 17,
+ isc_sockstatscounter_tcp4bindfail = 18,
+ isc_sockstatscounter_tcp6bindfail = 19,
+ isc_sockstatscounter_unixbindfail = 20,
+ isc_sockstatscounter_fdwatchbindfail = 21,
+
+ isc_sockstatscounter_udp4connect = 22,
+ isc_sockstatscounter_udp6connect = 23,
+ isc_sockstatscounter_tcp4connect = 24,
+ isc_sockstatscounter_tcp6connect = 25,
+ isc_sockstatscounter_unixconnect = 26,
+ isc_sockstatscounter_fdwatchconnect = 27,
+
+ isc_sockstatscounter_udp4connectfail = 28,
+ isc_sockstatscounter_udp6connectfail = 29,
+ isc_sockstatscounter_tcp4connectfail = 30,
+ isc_sockstatscounter_tcp6connectfail = 31,
+ isc_sockstatscounter_unixconnectfail = 32,
+ isc_sockstatscounter_fdwatchconnectfail = 33,
+
+ isc_sockstatscounter_tcp4accept = 34,
+ isc_sockstatscounter_tcp6accept = 35,
+ isc_sockstatscounter_unixaccept = 36,
+
+ isc_sockstatscounter_tcp4acceptfail = 37,
+ isc_sockstatscounter_tcp6acceptfail = 38,
+ isc_sockstatscounter_unixacceptfail = 39,
+
+ isc_sockstatscounter_udp4sendfail = 40,
+ isc_sockstatscounter_udp6sendfail = 41,
+ isc_sockstatscounter_tcp4sendfail = 42,
+ isc_sockstatscounter_tcp6sendfail = 43,
+ isc_sockstatscounter_unixsendfail = 44,
+ isc_sockstatscounter_fdwatchsendfail = 45,
+
+ isc_sockstatscounter_udp4recvfail = 46,
+ isc_sockstatscounter_udp6recvfail = 47,
+ isc_sockstatscounter_tcp4recvfail = 48,
+ isc_sockstatscounter_tcp6recvfail = 49,
+ isc_sockstatscounter_unixrecvfail = 50,
+ isc_sockstatscounter_fdwatchrecvfail = 51,
+
+ isc_sockstatscounter_max = 52
+};
+
+/***
+ *** Types
+ ***/
+
+struct isc_socketevent {
+ ISC_EVENT_COMMON(isc_socketevent_t);
+ isc_result_t result; /*%< OK, EOF, whatever else */
+ unsigned int minimum; /*%< minimum i/o for event */
+ unsigned int n; /*%< bytes read or written */
+ unsigned int offset; /*%< offset into buffer list */
+ isc_region_t region; /*%< for single-buffer i/o */
+ isc_bufferlist_t bufferlist; /*%< list of buffers */
+ isc_sockaddr_t address; /*%< source address */
+ isc_time_t timestamp; /*%< timestamp of packet recv */
+ struct in6_pktinfo pktinfo; /*%< ipv6 pktinfo */
+ isc_uint32_t attributes; /*%< see below */
+ isc_eventdestructor_t destroy; /*%< original destructor */
+};
+
+typedef struct isc_socket_newconnev isc_socket_newconnev_t;
+struct isc_socket_newconnev {
+ ISC_EVENT_COMMON(isc_socket_newconnev_t);
+ isc_socket_t * newsocket;
+ isc_result_t result; /*%< OK, EOF, whatever else */
+ isc_sockaddr_t address; /*%< source address */
+};
+
+typedef struct isc_socket_connev isc_socket_connev_t;
+struct isc_socket_connev {
+ ISC_EVENT_COMMON(isc_socket_connev_t);
+ isc_result_t result; /*%< OK, EOF, whatever else */
+};
+
+/*@{*/
+/*!
+ * _ATTACHED: Internal use only.
+ * _TRUNC: Packet was truncated on receive.
+ * _CTRUNC: Packet control information was truncated. This can
+ * indicate that the packet is not complete, even though
+ * all the data is valid.
+ * _TIMESTAMP: The timestamp member is valid.
+ * _PKTINFO: The pktinfo member is valid.
+ * _MULTICAST: The UDP packet was received via a multicast transmission.
+ */
+#define ISC_SOCKEVENTATTR_ATTACHED 0x80000000U /* internal */
+#define ISC_SOCKEVENTATTR_TRUNC 0x00800000U /* public */
+#define ISC_SOCKEVENTATTR_CTRUNC 0x00400000U /* public */
+#define ISC_SOCKEVENTATTR_TIMESTAMP 0x00200000U /* public */
+#define ISC_SOCKEVENTATTR_PKTINFO 0x00100000U /* public */
+#define ISC_SOCKEVENTATTR_MULTICAST 0x00080000U /* public */
+/*@}*/
+
+#define ISC_SOCKEVENT_ANYEVENT (0)
+#define ISC_SOCKEVENT_RECVDONE (ISC_EVENTCLASS_SOCKET + 1)
+#define ISC_SOCKEVENT_SENDDONE (ISC_EVENTCLASS_SOCKET + 2)
+#define ISC_SOCKEVENT_NEWCONN (ISC_EVENTCLASS_SOCKET + 3)
+#define ISC_SOCKEVENT_CONNECT (ISC_EVENTCLASS_SOCKET + 4)
+
+/*
+ * Internal events.
+ */
+#define ISC_SOCKEVENT_INTR (ISC_EVENTCLASS_SOCKET + 256)
+#define ISC_SOCKEVENT_INTW (ISC_EVENTCLASS_SOCKET + 257)
+
+typedef enum {
+ isc_sockettype_udp = 1,
+ isc_sockettype_tcp = 2,
+ isc_sockettype_unix = 3,
+ isc_sockettype_fdwatch = 4
+} isc_sockettype_t;
+
+/*@{*/
+/*!
+ * How a socket should be shutdown in isc_socket_shutdown() calls.
+ */
+#define ISC_SOCKSHUT_RECV 0x00000001 /*%< close read side */
+#define ISC_SOCKSHUT_SEND 0x00000002 /*%< close write side */
+#define ISC_SOCKSHUT_ALL 0x00000003 /*%< close them all */
+/*@}*/
+
+/*@{*/
+/*!
+ * What I/O events to cancel in isc_socket_cancel() calls.
+ */
+#define ISC_SOCKCANCEL_RECV 0x00000001 /*%< cancel recv */
+#define ISC_SOCKCANCEL_SEND 0x00000002 /*%< cancel send */
+#define ISC_SOCKCANCEL_ACCEPT 0x00000004 /*%< cancel accept */
+#define ISC_SOCKCANCEL_CONNECT 0x00000008 /*%< cancel connect */
+#define ISC_SOCKCANCEL_ALL 0x0000000f /*%< cancel everything */
+/*@}*/
+
+/*@{*/
+/*!
+ * Flags for isc_socket_send() and isc_socket_recv() calls.
+ */
+#define ISC_SOCKFLAG_IMMEDIATE 0x00000001 /*%< send event only if needed */
+#define ISC_SOCKFLAG_NORETRY 0x00000002 /*%< drop failed UDP sends */
+/*@}*/
+
+/*@{*/
+/*!
+ * Flags for fdwatchcreate.
+ */
+#define ISC_SOCKFDWATCH_READ 0x00000001 /*%< watch for readable */
+#define ISC_SOCKFDWATCH_WRITE 0x00000002 /*%< watch for writable */
+/*@}*/
+
+/*% Socket and socket manager methods */
+typedef struct isc_socketmgrmethods {
+ void (*destroy)(isc_socketmgr_t **managerp);
+ isc_result_t (*socketcreate)(isc_socketmgr_t *manager, int pf,
+ isc_sockettype_t type,
+ isc_socket_t **socketp);
+ isc_result_t (*fdwatchcreate)(isc_socketmgr_t *manager, int fd,
+ int flags,
+ isc_sockfdwatch_t callback,
+ void *cbarg, isc_task_t *task,
+ isc_socket_t **socketp);
+} isc_socketmgrmethods_t;
+
+typedef struct isc_socketmethods {
+ void (*attach)(isc_socket_t *sock,
+ isc_socket_t **socketp);
+ void (*detach)(isc_socket_t **socketp);
+ isc_result_t (*bind)(isc_socket_t *sock, isc_sockaddr_t *sockaddr,
+ unsigned int options);
+ isc_result_t (*sendto)(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg, isc_sockaddr_t *address,
+ struct in6_pktinfo *pktinfo);
+ isc_result_t (*connect)(isc_socket_t *sock, isc_sockaddr_t *addr,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ isc_result_t (*recv)(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_taskaction_t action, const void *arg);
+ void (*cancel)(isc_socket_t *sock, isc_task_t *task,
+ unsigned int how);
+ isc_result_t (*getsockname)(isc_socket_t *sock,
+ isc_sockaddr_t *addressp);
+ isc_sockettype_t (*gettype)(isc_socket_t *sock);
+ void (*ipv6only)(isc_socket_t *sock, isc_boolean_t yes);
+ isc_result_t (*fdwatchpoke)(isc_socket_t *sock, int flags);
+ isc_result_t (*dup)(isc_socket_t *sock,
+ isc_socket_t **socketp);
+ int (*getfd)(isc_socket_t *sock);
+} isc_socketmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a socket manager
+ * object implementation's version of an isc_socketmgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. socket implementations
+ * may change the structure. 'magic' must be ISCAPI_SOCKETMGR_MAGIC for any
+ * of the isc_socket_ routines to work. socket implementations must maintain
+ * all socket invariants.
+ * In effect, this definition is used only for non-BIND9 version ("export")
+ * of the library, and the export version does not work for win32. So, to avoid
+ * the definition conflict with win32/socket.c, we enable this definition only
+ * for non-Win32 (i.e. Unix) platforms.
+ */
+#ifndef WIN32
+struct isc_socketmgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_socketmgrmethods_t *methods;
+};
+#endif
+
+#define ISCAPI_SOCKETMGR_MAGIC ISC_MAGIC('A','s','m','g')
+#define ISCAPI_SOCKETMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_SOCKETMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a socket object. The same note as
+ * that for the socketmgr structure applies.
+ */
+#ifndef WIN32
+struct isc_socket {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_socketmethods_t *methods;
+};
+#endif
+
+#define ISCAPI_SOCKET_MAGIC ISC_MAGIC('A','s','c','t')
+#define ISCAPI_SOCKET_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_SOCKET_MAGIC)
+
+/***
+ *** Socket and Socket Manager Functions
+ ***
+ *** Note: all Ensures conditions apply only if the result is success for
+ *** those functions which return an isc_result.
+ ***/
+
+isc_result_t
+isc_socket_fdwatchcreate(isc_socketmgr_t *manager,
+ int fd,
+ int flags,
+ isc_sockfdwatch_t callback,
+ void *cbarg,
+ isc_task_t *task,
+ isc_socket_t **socketp);
+/*%<
+ * Create a new file descriptor watch socket managed by 'manager'.
+ *
+ * Note:
+ *
+ *\li 'fd' is the already-opened file descriptor.
+ *\li This function is not available on Windows.
+ *\li The callback function is called "in-line" - this means the function
+ * needs to return as fast as possible, as all other I/O will be suspended
+ * until the callback completes.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid manager
+ *
+ *\li 'socketp' is a valid pointer, and *socketp == NULL
+ *
+ *\li 'fd' be opened.
+ *
+ * Ensures:
+ *
+ * '*socketp' is attached to the newly created fdwatch socket
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_NORESOURCES
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_fdwatchpoke(isc_socket_t *sock,
+ int flags);
+/*%<
+ * Poke a file descriptor watch socket informing the manager that it
+ * should restart watching the socket
+ *
+ * Note:
+ *
+ *\li 'sock' is the socket returned by isc_socket_fdwatchcreate
+ *
+ *\li 'flags' indicates what the manager should watch for on the socket
+ * in addition to what it may already be watching. It can be one or
+ * both of ISC_SOCKFDWATCH_READ and ISC_SOCKFDWATCH_WRITE. To
+ * temporarily disable watching on a socket the value indicating
+ * no more data should be returned from the call back routine.
+ *
+ *\li This function is not available on Windows.
+ *
+ * Requires:
+ *
+ *\li 'sock' is a valid isc socket
+ *
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ */
+
+isc_result_t
+isc_socket_create(isc_socketmgr_t *manager,
+ int pf,
+ isc_sockettype_t type,
+ isc_socket_t **socketp);
+/*%<
+ * Create a new 'type' socket managed by 'manager'.
+ *
+ * For isc_sockettype_fdwatch sockets you should use isc_socket_fdwatchcreate()
+ * rather than isc_socket_create().
+ *
+ * Note:
+ *
+ *\li 'pf' is the desired protocol family, e.g. PF_INET or PF_INET6.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid manager
+ *
+ *\li 'socketp' is a valid pointer, and *socketp == NULL
+ *
+ *\li 'type' is not isc_sockettype_fdwatch
+ *
+ * Ensures:
+ *
+ * '*socketp' is attached to the newly created socket
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_NORESOURCES
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_dup(isc_socket_t *sock0, isc_socket_t **socketp);
+/*%<
+ * Duplicate an existing socket, reusing its file descriptor.
+ */
+
+void
+isc_socket_cancel(isc_socket_t *sock, isc_task_t *task,
+ unsigned int how);
+/*%<
+ * Cancel pending I/O of the type specified by "how".
+ *
+ * Note: if "task" is NULL, then the cancel applies to all tasks using the
+ * socket.
+ *
+ * Requires:
+ *
+ * \li "socket" is a valid socket
+ *
+ * \li "task" is NULL or a valid task
+ *
+ * "how" is a bitmask describing the type of cancelation to perform.
+ * The type ISC_SOCKCANCEL_ALL will cancel all pending I/O on this
+ * socket.
+ *
+ * \li ISC_SOCKCANCEL_RECV:
+ * Cancel pending isc_socket_recv() calls.
+ *
+ * \li ISC_SOCKCANCEL_SEND:
+ * Cancel pending isc_socket_send() and isc_socket_sendto() calls.
+ *
+ * \li ISC_SOCKCANCEL_ACCEPT:
+ * Cancel pending isc_socket_accept() calls.
+ *
+ * \li ISC_SOCKCANCEL_CONNECT:
+ * Cancel pending isc_socket_connect() call.
+ */
+
+void
+isc_socket_shutdown(isc_socket_t *sock, unsigned int how);
+/*%<
+ * Shutdown 'socket' according to 'how'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid socket.
+ *
+ * \li 'task' is NULL or is a valid task.
+ *
+ * \li If 'how' is 'ISC_SOCKSHUT_RECV' or 'ISC_SOCKSHUT_ALL' then
+ *
+ * The read queue must be empty.
+ *
+ * No further read requests may be made.
+ *
+ * \li If 'how' is 'ISC_SOCKSHUT_SEND' or 'ISC_SOCKSHUT_ALL' then
+ *
+ * The write queue must be empty.
+ *
+ * No further write requests may be made.
+ */
+
+void
+isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp);
+/*%<
+ * Attach *socketp to socket.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid socket.
+ *
+ * \li 'socketp' points to a NULL socket.
+ *
+ * Ensures:
+ *
+ * \li *socketp is attached to socket.
+ */
+
+void
+isc_socket_detach(isc_socket_t **socketp);
+/*%<
+ * Detach *socketp from its socket.
+ *
+ * Requires:
+ *
+ * \li 'socketp' points to a valid socket.
+ *
+ * \li If '*socketp' is the last reference to the socket,
+ * then:
+ *
+ * There must be no pending I/O requests.
+ *
+ * Ensures:
+ *
+ * \li *socketp is NULL.
+ *
+ * \li If '*socketp' is the last reference to the socket,
+ * then:
+ *
+ * The socket will be shutdown (both reading and writing)
+ * for all tasks.
+ *
+ * All resources used by the socket have been freed
+ */
+
+isc_result_t
+isc_socket_open(isc_socket_t *sock);
+/*%<
+ * Open a new socket file descriptor of the given socket structure. It simply
+ * opens a new descriptor; all of the other parameters including the socket
+ * type are inherited from the existing socket. This function is provided to
+ * avoid overhead of destroying and creating sockets when many short-lived
+ * sockets are frequently opened and closed. When the efficiency is not an
+ * issue, it should be safer to detach the unused socket and re-create a new
+ * one. This optimization may not be available for some systems, in which
+ * case this function will return ISC_R_NOTIMPLEMENTED and must not be used.
+ *
+ * isc_socket_open() should not be called on sockets created by
+ * isc_socket_fdwatchcreate().
+ *
+ * Requires:
+ *
+ * \li there must be no other reference to this socket.
+ *
+ * \li 'socket' is a valid and previously closed by isc_socket_close()
+ *
+ * \li 'sock->type' is not isc_sockettype_fdwatch
+ *
+ * Returns:
+ * Same as isc_socket_create().
+ * \li ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_socket_close(isc_socket_t *sock);
+/*%<
+ * Close a socket file descriptor of the given socket structure. This function
+ * is provided as an alternative to destroying an unused socket when overhead
+ * destroying/re-creating sockets can be significant, and is expected to be
+ * used with isc_socket_open(). This optimization may not be available for some
+ * systems, in which case this function will return ISC_R_NOTIMPLEMENTED and
+ * must not be used.
+ *
+ * isc_socket_close() should not be called on sockets created by
+ * isc_socket_fdwatchcreate().
+ *
+ * Requires:
+ *
+ * \li The socket must have a valid descriptor.
+ *
+ * \li There must be no other reference to this socket.
+ *
+ * \li There must be no pending I/O requests.
+ *
+ * \li 'sock->type' is not isc_sockettype_fdwatch
+ *
+ * Returns:
+ * \li #ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_socket_bind(isc_socket_t *sock, isc_sockaddr_t *addressp,
+ unsigned int options);
+/*%<
+ * Bind 'socket' to '*addressp'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid socket
+ *
+ * \li 'addressp' points to a valid isc_sockaddr.
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOPERM
+ * \li ISC_R_ADDRNOTAVAIL
+ * \li ISC_R_ADDRINUSE
+ * \li ISC_R_BOUND
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_filter(isc_socket_t *sock, const char *filter);
+/*%<
+ * Inform the kernel that it should perform accept filtering.
+ * If filter is NULL the current filter will be removed.:w
+ */
+
+isc_result_t
+isc_socket_listen(isc_socket_t *sock, unsigned int backlog);
+/*%<
+ * Set listen mode on the socket. After this call, the only function that
+ * can be used (other than attach and detach) is isc_socket_accept().
+ *
+ * Notes:
+ *
+ * \li 'backlog' is as in the UNIX system call listen() and may be
+ * ignored by non-UNIX implementations.
+ *
+ * \li If 'backlog' is zero, a reasonable system default is used, usually
+ * SOMAXCONN.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid, bound TCP socket or a valid, bound UNIX socket.
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_accept(isc_socket_t *sock,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+/*%<
+ * Queue accept event. When a new connection is received, the task will
+ * get an ISC_SOCKEVENT_NEWCONN event with the sender set to the listen
+ * socket. The new socket structure is sent inside the isc_socket_newconnev_t
+ * event type, and is attached to the task 'task'.
+ *
+ * REQUIRES:
+ * \li 'socket' is a valid TCP socket that isc_socket_listen() was called
+ * on.
+ *
+ * \li 'task' is a valid task
+ *
+ * \li 'action' is a valid action
+ *
+ * RETURNS:
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_connect(isc_socket_t *sock, isc_sockaddr_t *addressp,
+ isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+/*%<
+ * Connect 'socket' to peer with address *saddr. When the connection
+ * succeeds, or when an error occurs, a CONNECT event with action 'action'
+ * and arg 'arg' will be posted to the event queue for 'task'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid TCP socket
+ *
+ * \li 'addressp' points to a valid isc_sockaddr
+ *
+ * \li 'task' is a valid task
+ *
+ * \li 'action' is a valid action
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_NOMEMORY
+ * \li ISC_R_UNEXPECTED
+ *
+ * Posted event's result code:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TIMEDOUT
+ * \li ISC_R_CONNREFUSED
+ * \li ISC_R_NETUNREACH
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_getpeername(isc_socket_t *sock, isc_sockaddr_t *addressp);
+/*%<
+ * Get the name of the peer connected to 'socket'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid TCP socket.
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TOOSMALL
+ * \li ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_socket_getsockname(isc_socket_t *sock, isc_sockaddr_t *addressp);
+/*%<
+ * Get the name of 'socket'.
+ *
+ * Requires:
+ *
+ * \li 'socket' is a valid socket.
+ *
+ * Returns:
+ *
+ * \li ISC_R_SUCCESS
+ * \li ISC_R_TOOSMALL
+ * \li ISC_R_UNEXPECTED
+ */
+
+/*@{*/
+isc_result_t
+isc_socket_recv(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+isc_result_t
+isc_socket_recvv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ unsigned int minimum,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+
+isc_result_t
+isc_socket_recv2(isc_socket_t *sock, isc_region_t *region,
+ unsigned int minimum, isc_task_t *task,
+ isc_socketevent_t *event, unsigned int flags);
+
+/*!
+ * Receive from 'socket', storing the results in region.
+ *
+ * Notes:
+ *
+ *\li Let 'length' refer to the length of 'region' or to the sum of all
+ * available regions in the list of buffers '*buflist'.
+ *
+ *\li If 'minimum' is non-zero and at least that many bytes are read,
+ * the completion event will be posted to the task 'task.' If minimum
+ * is zero, the exact number of bytes requested in the region must
+ * be read for an event to be posted. This only makes sense for TCP
+ * connections, and is always set to 1 byte for UDP.
+ *
+ *\li The read will complete when the desired number of bytes have been
+ * read, if end-of-input occurs, or if an error occurs. A read done
+ * event with the given 'action' and 'arg' will be posted to the
+ * event queue of 'task'.
+ *
+ *\li The caller may not modify 'region', the buffers which are passed
+ * into this function, or any data they refer to until the completion
+ * event is received.
+ *
+ *\li For isc_socket_recvv():
+ * On successful completion, '*buflist' will be empty, and the list of
+ * all buffers will be returned in the done event's 'bufferlist'
+ * member. On error return, '*buflist' will be unchanged.
+ *
+ *\li For isc_socket_recv2():
+ * 'event' is not NULL, and the non-socket specific fields are
+ * expected to be initialized.
+ *
+ *\li For isc_socket_recv2():
+ * The only defined value for 'flags' is ISC_SOCKFLAG_IMMEDIATE. If
+ * set and the operation completes, the return value will be
+ * ISC_R_SUCCESS and the event will be filled in and not sent. If the
+ * operation does not complete, the return value will be
+ * ISC_R_INPROGRESS and the event will be sent when the operation
+ * completes.
+ *
+ * Requires:
+ *
+ *\li 'socket' is a valid, bound socket.
+ *
+ *\li For isc_socket_recv():
+ * 'region' is a valid region
+ *
+ *\li For isc_socket_recvv():
+ * 'buflist' is non-NULL, and '*buflist' contain at least one buffer.
+ *
+ *\li 'task' is a valid task
+ *
+ *\li For isc_socket_recv() and isc_socket_recvv():
+ * action != NULL and is a valid action
+ *
+ *\li For isc_socket_recv2():
+ * event != NULL
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_INPROGRESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ *
+ * Event results:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_UNEXPECTED
+ *\li XXX needs other net-type errors
+ */
+/*@}*/
+
+/*@{*/
+isc_result_t
+isc_socket_send(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+isc_result_t
+isc_socket_sendto(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
+isc_result_t
+isc_socket_sendv(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg);
+isc_result_t
+isc_socket_sendtov(isc_socket_t *sock, isc_bufferlist_t *buflist,
+ isc_task_t *task, isc_taskaction_t action, const void *arg,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo);
+isc_result_t
+isc_socket_sendto2(isc_socket_t *sock, isc_region_t *region,
+ isc_task_t *task,
+ isc_sockaddr_t *address, struct in6_pktinfo *pktinfo,
+ isc_socketevent_t *event, unsigned int flags);
+
+/*!
+ * Send the contents of 'region' to the socket's peer.
+ *
+ * Notes:
+ *
+ *\li Shutting down the requestor's task *may* result in any
+ * still pending writes being dropped or completed, depending on the
+ * underlying OS implementation.
+ *
+ *\li If 'action' is NULL, then no completion event will be posted.
+ *
+ *\li The caller may not modify 'region', the buffers which are passed
+ * into this function, or any data they refer to until the completion
+ * event is received.
+ *
+ *\li For isc_socket_sendv() and isc_socket_sendtov():
+ * On successful completion, '*buflist' will be empty, and the list of
+ * all buffers will be returned in the done event's 'bufferlist'
+ * member. On error return, '*buflist' will be unchanged.
+ *
+ *\li For isc_socket_sendto2():
+ * 'event' is not NULL, and the non-socket specific fields are
+ * expected to be initialized.
+ *
+ *\li For isc_socket_sendto2():
+ * The only defined values for 'flags' are ISC_SOCKFLAG_IMMEDIATE
+ * and ISC_SOCKFLAG_NORETRY.
+ *
+ *\li If ISC_SOCKFLAG_IMMEDIATE is set and the operation completes, the
+ * return value will be ISC_R_SUCCESS and the event will be filled
+ * in and not sent. If the operation does not complete, the return
+ * value will be ISC_R_INPROGRESS and the event will be sent when
+ * the operation completes.
+ *
+ *\li ISC_SOCKFLAG_NORETRY can only be set for UDP sockets. If set
+ * and the send operation fails due to a transient error, the send
+ * will not be retried and the error will be indicated in the event.
+ * Using this option along with ISC_SOCKFLAG_IMMEDIATE allows the caller
+ * to specify a region that is allocated on the stack.
+ *
+ * Requires:
+ *
+ *\li 'socket' is a valid, bound socket.
+ *
+ *\li For isc_socket_send():
+ * 'region' is a valid region
+ *
+ *\li For isc_socket_sendv() and isc_socket_sendtov():
+ * 'buflist' is non-NULL, and '*buflist' contain at least one buffer.
+ *
+ *\li 'task' is a valid task
+ *
+ *\li For isc_socket_sendv(), isc_socket_sendtov(), isc_socket_send(), and
+ * isc_socket_sendto():
+ * action == NULL or is a valid action
+ *
+ *\li For isc_socket_sendto2():
+ * event != NULL
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_INPROGRESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ *
+ * Event results:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_UNEXPECTED
+ *\li XXX needs other net-type errors
+ */
+/*@}*/
+
+isc_result_t
+isc_socketmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_socketmgr_t **managerp);
+
+isc_result_t
+isc_socketmgr_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+
+isc_result_t
+isc_socketmgr_create2(isc_mem_t *mctx, isc_socketmgr_t **managerp,
+ unsigned int maxsocks);
+/*%<
+ * Create a socket manager. If "maxsocks" is non-zero, it specifies the
+ * maximum number of sockets that the created manager should handle.
+ * isc_socketmgr_create() is equivalent of isc_socketmgr_create2() with
+ * "maxsocks" being zero.
+ * isc_socketmgr_createinctx() also associates the new manager with the
+ * specified application context.
+ *
+ * Notes:
+ *
+ *\li All memory will be allocated in memory context 'mctx'.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'managerp' points to a NULL isc_socketmgr_t.
+ *
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
+ * Ensures:
+ *
+ *\li '*managerp' is a valid isc_socketmgr_t.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ *\li #ISC_R_NOTIMPLEMENTED
+ */
+
+isc_result_t
+isc_socketmgr_getmaxsockets(isc_socketmgr_t *manager, unsigned int *nsockp);
+/*%<
+ * Returns in "*nsockp" the maximum number of sockets this manager may open.
+ *
+ * Requires:
+ *
+ *\li '*manager' is a valid isc_socketmgr_t.
+ *\li 'nsockp' is not NULL.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOTIMPLEMENTED
+ */
+
+void
+isc_socketmgr_setstats(isc_socketmgr_t *manager, isc_stats_t *stats);
+/*%<
+ * Set a general socket statistics counter set 'stats' for 'manager'.
+ *
+ * Requires:
+ * \li 'manager' is valid, hasn't opened any socket, and doesn't have
+ * stats already set.
+ *
+ *\li stats is a valid statistics supporting socket statistics counters
+ * (see above).
+ */
+
+void
+isc_socketmgr_destroy(isc_socketmgr_t **managerp);
+/*%<
+ * Destroy a socket manager.
+ *
+ * Notes:
+ *
+ *\li This routine blocks until there are no sockets left in the manager,
+ * so if the caller holds any socket references using the manager, it
+ * must detach them before calling isc_socketmgr_destroy() or it will
+ * block forever.
+ *
+ * Requires:
+ *
+ *\li '*managerp' is a valid isc_socketmgr_t.
+ *
+ *\li All sockets managed by this manager are fully detached.
+ *
+ * Ensures:
+ *
+ *\li *managerp == NULL
+ *
+ *\li All resources used by the manager have been freed.
+ */
+
+isc_sockettype_t
+isc_socket_gettype(isc_socket_t *sock);
+/*%<
+ * Returns the socket type for "sock."
+ *
+ * Requires:
+ *
+ *\li "sock" is a valid socket.
+ */
+
+/*@{*/
+isc_boolean_t
+isc_socket_isbound(isc_socket_t *sock);
+
+void
+isc_socket_ipv6only(isc_socket_t *sock, isc_boolean_t yes);
+/*%<
+ * If the socket is an IPv6 socket set/clear the IPV6_IPV6ONLY socket
+ * option if the host OS supports this option.
+ *
+ * Requires:
+ *\li 'sock' is a valid socket.
+ */
+/*@}*/
+
+void
+isc_socket_cleanunix(isc_sockaddr_t *addr, isc_boolean_t active);
+
+/*%<
+ * Cleanup UNIX domain sockets in the file-system. If 'active' is true
+ * then just unlink the socket. If 'active' is false try to determine
+ * if there is a listener of the socket or not. If no listener is found
+ * then unlink socket.
+ *
+ * Prior to unlinking the path is tested to see if it a socket.
+ *
+ * Note: there are a number of race conditions which cannot be avoided
+ * both in the filesystem and any application using UNIX domain
+ * sockets (e.g. socket is tested between bind() and listen(),
+ * the socket is deleted and replaced in the file-system between
+ * stat() and unlink()).
+ */
+
+isc_result_t
+isc_socket_permunix(isc_sockaddr_t *sockaddr, isc_uint32_t perm,
+ isc_uint32_t owner, isc_uint32_t group);
+/*%<
+ * Set ownership and file permissions on the UNIX domain socket.
+ *
+ * Note: On Solaris and SunOS this secures the directory containing
+ * the socket as Solaris and SunOS do not honour the filesystem
+ * permissions on the socket.
+ *
+ * Requires:
+ * \li 'sockaddr' to be a valid UNIX domain sockaddr.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_FAILURE
+ */
+
+void isc_socket_setname(isc_socket_t *sock, const char *name, void *tag);
+/*%<
+ * Set the name and optional tag for a socket. This allows tracking of the
+ * owner or purpose for this socket, and is useful for tracing and statistics
+ * reporting.
+ */
+
+const char *isc_socket_getname(isc_socket_t *sock);
+/*%<
+ * Get the name associated with a socket, if any.
+ */
+
+void *isc_socket_gettag(isc_socket_t *sock);
+/*%<
+ * Get the tag associated with a socket, if any.
+ */
+
+int isc_socket_getfd(isc_socket_t *sock);
+/*%<
+ * Get the file descriptor associated with a socket
+ */
+
+void
+isc__socketmgr_setreserved(isc_socketmgr_t *mgr, isc_uint32_t);
+/*%<
+ * Temporary. For use by named only.
+ */
+
+void
+isc__socketmgr_maxudp(isc_socketmgr_t *mgr, int maxudp);
+/*%<
+ * Test interface. Drop UDP packet > 'maxudp'.
+ */
+
+#ifdef HAVE_LIBXML2
+
+void
+isc_socketmgr_renderxml(isc_socketmgr_t *mgr, xmlTextWriterPtr writer);
+/*%<
+ * Render internal statistics and other state into the XML document.
+ */
+
+#endif /* HAVE_LIBXML2 */
+
+#ifdef USE_SOCKETIMPREGISTER
+/*%<
+ * See isc_socketmgr_create() above.
+ */
+typedef isc_result_t
+(*isc_socketmgrcreatefunc_t)(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+
+isc_result_t
+isc_socket_register(isc_socketmgrcreatefunc_t createfunc);
+/*%<
+ * Register a new socket I/O implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__socket_register(void);
+/*%<
+ * A short cut function that specifies the socket I/O module in the ISC
+ * library for isc_socket_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_SOCKETIMPREGISTER */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SOCKET_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/stdio.h b/contrib/ntp/libntp/lib/isc/include/isc/stdio.h
new file mode 100644
index 000000000000..1a7ae642d5eb
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/stdio.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: stdio.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_STDIO_H
+#define ISC_STDIO_H 1
+
+/*! \file isc/stdio.h */
+
+/*%
+ * These functions are wrappers around the corresponding stdio functions.
+ *
+ * They return a detailed error code in the form of an an isc_result_t. ANSI C
+ * does not guarantee that stdio functions set errno, hence these functions
+ * must use platform dependent methods (e.g., the POSIX errno) to construct the
+ * error code.
+ */
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+ISC_LANG_BEGINDECLS
+
+/*% Open */
+isc_result_t
+isc_stdio_open(const char *filename, const char *mode, FILE **fp);
+
+/*% Close */
+isc_result_t
+isc_stdio_close(FILE *f);
+
+/*% Seek */
+isc_result_t
+isc_stdio_seek(FILE *f, long offset, int whence);
+
+/*% Read */
+isc_result_t
+isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f,
+ size_t *nret);
+
+/*% Write */
+isc_result_t
+isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f,
+ size_t *nret);
+
+/*% Flush */
+isc_result_t
+isc_stdio_flush(FILE *f);
+
+isc_result_t
+isc_stdio_sync(FILE *f);
+/*%<
+ * Invoke fsync() on the file descriptor underlying an stdio stream, or an
+ * equivalent system-dependent operation. Note that this function has no
+ * direct counterpart in the stdio library.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STDIO_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/string.h b/contrib/ntp/libntp/lib/isc/include/isc/string.h
new file mode 100644
index 000000000000..395b550218fc
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/string.h
@@ -0,0 +1,249 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: string.h,v 1.23 2007/09/13 04:48:16 each Exp $ */
+
+#ifndef ISC_STRING_H
+#define ISC_STRING_H 1
+
+/*! \file isc/string.h */
+
+#include <isc/formatcheck.h>
+#include <isc/int.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#include <string.h>
+
+#ifdef ISC_PLATFORM_HAVESTRINGSH
+#include <strings.h>
+#endif
+
+#define ISC_STRING_MAGIC 0x5e
+
+ISC_LANG_BEGINDECLS
+
+isc_uint64_t
+isc_string_touint64(char *source, char **endp, int base);
+/*%<
+ * Convert the string pointed to by 'source' to isc_uint64_t.
+ *
+ * On successful conversion 'endp' points to the first character
+ * after conversion is complete.
+ *
+ * 'base': 0 or 2..36
+ *
+ * If base is 0 the base is computed from the string type.
+ *
+ * On error 'endp' points to 'source'.
+ */
+
+isc_result_t
+isc_string_copy(char *target, size_t size, const char *source);
+/*
+ * Copy the string pointed to by 'source' to 'target' which is a
+ * pointer to a string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'source' was successfully copied to 'target'.
+ * ISC_R_NOSPACE -- 'source' could not be copied since 'target'
+ * is too small.
+ */
+
+void
+isc_string_copy_truncate(char *target, size_t size, const char *source);
+/*
+ * Copy the string pointed to by 'source' to 'target' which is a
+ * pointer to a string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+isc_result_t
+isc_string_append(char *target, size_t size, const char *source);
+/*
+ * Append the string pointed to by 'source' to 'target' which is a
+ * pointer to a NUL terminated string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a NUL terminated char[] of at
+ * least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'source' was successfully appended to 'target'.
+ * ISC_R_NOSPACE -- 'source' could not be appended since 'target'
+ * is too small.
+ */
+
+void
+isc_string_append_truncate(char *target, size_t size, const char *source);
+/*
+ * Append the string pointed to by 'source' to 'target' which is a
+ * pointer to a NUL terminated string of at least 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a NUL terminated char[] of at
+ * least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'source' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+isc_result_t
+isc_string_printf(char *target, size_t size, const char *format, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+/*
+ * Print 'format' to 'target' which is a pointer to a string of at least
+ * 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'format' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * If result == ISC_R_SUCCESS
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ *
+ * If result == ISC_R_NOSPACE
+ * 'target' is undefined.
+ *
+ * Returns:
+ * ISC_R_SUCCESS -- 'format' was successfully printed to 'target'.
+ * ISC_R_NOSPACE -- 'format' could not be printed to 'target' since it
+ * is too small.
+ */
+
+void
+isc_string_printf_truncate(char *target, size_t size, const char *format, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+/*
+ * Print 'format' to 'target' which is a pointer to a string of at least
+ * 'size' bytes.
+ *
+ * Requires:
+ * 'target' is a pointer to a char[] of at least 'size' bytes.
+ * 'size' an integer > 0.
+ * 'format' == NULL or points to a NUL terminated string.
+ *
+ * Ensures:
+ * 'target' will be a NUL terminated string of no more
+ * than 'size' bytes (including NUL).
+ */
+
+
+char *
+isc_string_regiondup(isc_mem_t *mctx, const isc_region_t *source);
+/*
+ * Copy the region pointed to by r to a NUL terminated string
+ * allocated from the memory context pointed to by mctx.
+ *
+ * The result should be deallocated using isc_mem_free()
+ *
+ * Requires:
+ * 'mctx' is a point to a valid memory context.
+ * 'source' is a pointer to a valid region.
+ *
+ * Returns:
+ * a pointer to a NUL terminated string or
+ * NULL if memory for the copy could not be allocated
+ *
+ */
+
+int
+isc_tsmemcmp(const void *p1, const void *p2, size_t len);
+/*
+ * Lexicographic compare 'len' unsigned bytes from 'p1' and 'p2'
+ * like 'memcmp()'.
+ *
+ * This function is safe from timing attacks as it has a runtime that
+ * only depends on 'len' and has no early-out option.
+ *
+ * Use this to check MACs and other material that is security sensitive.
+ *
+ * Returns:
+ * (let x be the byte offset of the first different byte)
+ * -1 if (u_char)p1[x] < (u_char)p2[x]
+ * 1 if (u_char)p1[x] > (u_char)p2[x]
+ * 0 if byte series are equal
+ */
+
+char *
+isc_string_separate(char **stringp, const char *delim);
+
+#ifdef ISC_PLATFORM_NEEDSTRSEP
+#define strsep isc_string_separate
+#endif
+
+#ifdef ISC_PLATFORM_NEEDMEMMOVE
+#define memmove(a,b,c) bcopy(b,a,c)
+#endif
+
+size_t
+isc_string_strlcpy(char *dst, const char *src, size_t size);
+
+
+#ifdef ISC_PLATFORM_NEEDSTRLCPY
+#define strlcpy isc_string_strlcpy
+#endif
+
+
+size_t
+isc_string_strlcat(char *dst, const char *src, size_t size);
+
+#ifdef ISC_PLATFORM_NEEDSTRLCAT
+#define strlcat isc_string_strlcat
+#endif
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STRING_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/task.h b/contrib/ntp/libntp/lib/isc/include/isc/task.h
new file mode 100644
index 000000000000..594d80f34510
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/task.h
@@ -0,0 +1,796 @@
+/*
+ * Copyright (C) 2004-2007, 2009-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_TASK_H
+#define ISC_TASK_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/task.h
+ * \brief The task system provides a lightweight execution context, which is
+ * basically an event queue.
+
+ * When a task's event queue is non-empty, the
+ * task is runnable. A small work crew of threads, typically one per CPU,
+ * execute runnable tasks by dispatching the events on the tasks' event
+ * queues. Context switching between tasks is fast.
+ *
+ * \li MP:
+ * The module ensures appropriate synchronization of data structures it
+ * creates and manipulates.
+ * The caller must ensure that isc_taskmgr_destroy() is called only
+ * once for a given manager.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ *
+ * \section purge Purging and Unsending
+ *
+ * Events which have been queued for a task but not delivered may be removed
+ * from the task's event queue by purging or unsending.
+ *
+ * With both types, the caller specifies a matching pattern that selects
+ * events based upon their sender, type, and tag.
+ *
+ * Purging calls isc_event_free() on the matching events.
+ *
+ * Unsending returns a list of events that matched the pattern.
+ * The caller is then responsible for them.
+ *
+ * Consumers of events should purge, not unsend.
+ *
+ * Producers of events often want to remove events when the caller indicates
+ * it is no longer interested in the object, e.g. by canceling a timer.
+ * Sometimes this can be done by purging, but for some event types, the
+ * calls to isc_event_free() cause deadlock because the event free routine
+ * wants to acquire a lock the caller is already holding. Unsending instead
+ * of purging solves this problem. As a general rule, producers should only
+ * unsend events which they have sent.
+ */
+
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/eventclass.h>
+#include <isc/lang.h>
+#include <isc/stdtime.h>
+#include <isc/types.h>
+#include <isc/xml.h>
+
+#define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0)
+#define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1)
+#define ISC_TASKEVENT_TEST (ISC_EVENTCLASS_TASK + 1)
+#define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535)
+
+/*****
+ ***** Tasks.
+ *****/
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+typedef enum {
+ isc_taskmgrmode_normal = 0,
+ isc_taskmgrmode_privileged
+} isc_taskmgrmode_t;
+
+/*% Task and task manager methods */
+typedef struct isc_taskmgrmethods {
+ void (*destroy)(isc_taskmgr_t **managerp);
+ void (*setmode)(isc_taskmgr_t *manager,
+ isc_taskmgrmode_t mode);
+ isc_taskmgrmode_t (*mode)(isc_taskmgr_t *manager);
+ isc_result_t (*taskcreate)(isc_taskmgr_t *manager,
+ unsigned int quantum,
+ isc_task_t **taskp);
+} isc_taskmgrmethods_t;
+
+typedef struct isc_taskmethods {
+ void (*attach)(isc_task_t *source, isc_task_t **targetp);
+ void (*detach)(isc_task_t **taskp);
+ void (*destroy)(isc_task_t **taskp);
+ void (*send)(isc_task_t *task, isc_event_t **eventp);
+ void (*sendanddetach)(isc_task_t **taskp, isc_event_t **eventp);
+ unsigned int (*unsend)(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+ isc_result_t (*onshutdown)(isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+ void (*shutdown)(isc_task_t *task);
+ void (*setname)(isc_task_t *task, const char *name, void *tag);
+ unsigned int (*purgeevents)(isc_task_t *task, void *sender,
+ isc_eventtype_t type, void *tag);
+ unsigned int (*purgerange)(isc_task_t *task, void *sender,
+ isc_eventtype_t first, isc_eventtype_t last,
+ void *tag);
+ isc_result_t (*beginexclusive)(isc_task_t *task);
+ void (*endexclusive)(isc_task_t *task);
+ void (*setprivilege)(isc_task_t *task, isc_boolean_t priv);
+ isc_boolean_t (*privilege)(isc_task_t *task);
+} isc_taskmethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a task manager
+ * object implementation's version of an isc_taskmgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. task implementations
+ * may change the structure. 'magic' must be ISCAPI_TASKMGR_MAGIC for any
+ * of the isc_task_ routines to work. task implementations must maintain
+ * all task invariants.
+ */
+struct isc_taskmgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_taskmgrmethods_t *methods;
+};
+
+#define ISCAPI_TASKMGR_MAGIC ISC_MAGIC('A','t','m','g')
+#define ISCAPI_TASKMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_TASKMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a task object. The same note as
+ * that for the taskmgr structure applies.
+ */
+struct isc_task {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_taskmethods_t *methods;
+};
+
+#define ISCAPI_TASK_MAGIC ISC_MAGIC('A','t','s','t')
+#define ISCAPI_TASK_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_TASK_MAGIC)
+
+isc_result_t
+isc_task_create(isc_taskmgr_t *manager, unsigned int quantum,
+ isc_task_t **taskp);
+/*%<
+ * Create a task.
+ *
+ * Notes:
+ *
+ *\li If 'quantum' is non-zero, then only that many events can be dispatched
+ * before the task must yield to other tasks waiting to execute. If
+ * quantum is zero, then the default quantum of the task manager will
+ * be used.
+ *
+ *\li The 'quantum' option may be removed from isc_task_create() in the
+ * future. If this happens, isc_task_getquantum() and
+ * isc_task_setquantum() will be provided.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid task manager.
+ *
+ *\li taskp != NULL && *taskp == NULL
+ *
+ * Ensures:
+ *
+ *\li On success, '*taskp' is bound to the new task.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ *\li #ISC_R_SHUTTINGDOWN
+ */
+
+void
+isc_task_attach(isc_task_t *source, isc_task_t **targetp);
+/*%<
+ * Attach *targetp to source.
+ *
+ * Requires:
+ *
+ *\li 'source' is a valid task.
+ *
+ *\li 'targetp' points to a NULL isc_task_t *.
+ *
+ * Ensures:
+ *
+ *\li *targetp is attached to source.
+ */
+
+void
+isc_task_detach(isc_task_t **taskp);
+/*%<
+ * Detach *taskp from its task.
+ *
+ * Requires:
+ *
+ *\li '*taskp' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li *taskp is NULL.
+ *
+ *\li If '*taskp' is the last reference to the task, the task is idle (has
+ * an empty event queue), and has not been shutdown, the task will be
+ * shutdown.
+ *
+ *\li If '*taskp' is the last reference to the task and
+ * the task has been shutdown,
+ * all resources used by the task will be freed.
+ */
+
+void
+isc_task_send(isc_task_t *task, isc_event_t **eventp);
+/*%<
+ * Send '*event' to 'task'.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *\li eventp != NULL && *eventp != NULL.
+ *
+ * Ensures:
+ *
+ *\li *eventp == NULL.
+ */
+
+void
+isc_task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
+/*%<
+ * Send '*event' to '*taskp' and then detach '*taskp' from its
+ * task.
+ *
+ * Requires:
+ *
+ *\li '*taskp' is a valid task.
+ *\li eventp != NULL && *eventp != NULL.
+ *
+ * Ensures:
+ *
+ *\li *eventp == NULL.
+ *
+ *\li *taskp == NULL.
+ *
+ *\li If '*taskp' is the last reference to the task, the task is
+ * idle (has an empty event queue), and has not been shutdown,
+ * the task will be shutdown.
+ *
+ *\li If '*taskp' is the last reference to the task and
+ * the task has been shutdown,
+ * all resources used by the task will be freed.
+ */
+
+
+unsigned int
+isc_task_purgerange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag);
+/*%<
+ * Purge events from a task's event queue.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li last >= first
+ *
+ * Ensures:
+ *
+ *\li Events in the event queue of 'task' whose sender is 'sender', whose
+ * type is >= first and <= last, and whose tag is 'tag' will be purged,
+ * unless they are marked as unpurgable.
+ *
+ *\li A sender of NULL will match any sender. A NULL tag matches any
+ * tag.
+ *
+ * Returns:
+ *
+ *\li The number of events purged.
+ */
+
+unsigned int
+isc_task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag);
+/*%<
+ * Purge events from a task's event queue.
+ *
+ * Notes:
+ *
+ *\li This function is equivalent to
+ *
+ *\code
+ * isc_task_purgerange(task, sender, type, type, tag);
+ *\endcode
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li Events in the event queue of 'task' whose sender is 'sender', whose
+ * type is 'type', and whose tag is 'tag' will be purged, unless they
+ * are marked as unpurgable.
+ *
+ *\li A sender of NULL will match any sender. A NULL tag matches any
+ * tag.
+ *
+ * Returns:
+ *
+ *\li The number of events purged.
+ */
+
+isc_boolean_t
+isc_task_purgeevent(isc_task_t *task, isc_event_t *event);
+/*%<
+ * Purge 'event' from a task's event queue.
+ *
+ * XXXRTH: WARNING: This method may be removed before beta.
+ *
+ * Notes:
+ *
+ *\li If 'event' is on the task's event queue, it will be purged,
+ * unless it is marked as unpurgeable. 'event' does not have to be
+ * on the task's event queue; in fact, it can even be an invalid
+ * pointer. Purging only occurs if the event is actually on the task's
+ * event queue.
+ *
+ * \li Purging never changes the state of the task.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li 'event' is not in the event queue for 'task'.
+ *
+ * Returns:
+ *
+ *\li #ISC_TRUE The event was purged.
+ *\li #ISC_FALSE The event was not in the event queue,
+ * or was marked unpurgeable.
+ */
+
+unsigned int
+isc_task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag, isc_eventlist_t *events);
+/*%<
+ * Remove events from a task's event queue.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li last >= first.
+ *
+ *\li *events is a valid list.
+ *
+ * Ensures:
+ *
+ *\li Events in the event queue of 'task' whose sender is 'sender', whose
+ * type is >= first and <= last, and whose tag is 'tag' will be dequeued
+ * and appended to *events.
+ *
+ *\li A sender of NULL will match any sender. A NULL tag matches any
+ * tag.
+ *
+ * Returns:
+ *
+ *\li The number of events unsent.
+ */
+
+unsigned int
+isc_task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+/*%<
+ * Remove events from a task's event queue.
+ *
+ * Notes:
+ *
+ *\li This function is equivalent to
+ *
+ *\code
+ * isc_task_unsendrange(task, sender, type, type, tag, events);
+ *\endcode
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li *events is a valid list.
+ *
+ * Ensures:
+ *
+ *\li Events in the event queue of 'task' whose sender is 'sender', whose
+ * type is 'type', and whose tag is 'tag' will be dequeued and appended
+ * to *events.
+ *
+ * Returns:
+ *
+ *\li The number of events unsent.
+ */
+
+isc_result_t
+isc_task_onshutdown(isc_task_t *task, isc_taskaction_t action,
+ const void *arg);
+/*%<
+ * Send a shutdown event with action 'action' and argument 'arg' when
+ * 'task' is shutdown.
+ *
+ * Notes:
+ *
+ *\li Shutdown events are posted in LIFO order.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ *\li 'action' is a valid task action.
+ *
+ * Ensures:
+ *
+ *\li When the task is shutdown, shutdown events requested with
+ * isc_task_onshutdown() will be appended to the task's event queue.
+ *
+
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_TASKSHUTTINGDOWN Task is shutting down.
+ */
+
+void
+isc_task_shutdown(isc_task_t *task);
+/*%<
+ * Shutdown 'task'.
+ *
+ * Notes:
+ *
+ *\li Shutting down a task causes any shutdown events requested with
+ * isc_task_onshutdown() to be posted (in LIFO order). The task
+ * moves into a "shutting down" mode which prevents further calls
+ * to isc_task_onshutdown().
+ *
+ *\li Trying to shutdown a task that has already been shutdown has no
+ * effect.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li Any shutdown events requested with isc_task_onshutdown() have been
+ * posted (in LIFO order).
+ */
+
+void
+isc_task_destroy(isc_task_t **taskp);
+/*%<
+ * Destroy '*taskp'.
+ *
+ * Notes:
+ *
+ *\li This call is equivalent to:
+ *
+ *\code
+ * isc_task_shutdown(*taskp);
+ * isc_task_detach(taskp);
+ *\endcode
+ *
+ * Requires:
+ *
+ * '*taskp' is a valid task.
+ *
+ * Ensures:
+ *
+ *\li Any shutdown events requested with isc_task_onshutdown() have been
+ * posted (in LIFO order).
+ *
+ *\li *taskp == NULL
+ *
+ *\li If '*taskp' is the last reference to the task,
+ * all resources used by the task will be freed.
+ */
+
+void
+isc_task_setname(isc_task_t *task, const char *name, void *tag);
+/*%<
+ * Name 'task'.
+ *
+ * Notes:
+ *
+ *\li Only the first 15 characters of 'name' will be copied.
+ *
+ *\li Naming a task is currently only useful for debugging purposes.
+ *
+ * Requires:
+ *
+ *\li 'task' is a valid task.
+ */
+
+const char *
+isc_task_getname(isc_task_t *task);
+/*%<
+ * Get the name of 'task', as previously set using isc_task_setname().
+ *
+ * Notes:
+ *\li This function is for debugging purposes only.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ *
+ * Returns:
+ *\li A non-NULL pointer to a null-terminated string.
+ * If the task has not been named, the string is
+ * empty.
+ *
+ */
+
+void *
+isc_task_gettag(isc_task_t *task);
+/*%<
+ * Get the tag value for 'task', as previously set using isc_task_settag().
+ *
+ * Notes:
+ *\li This function is for debugging purposes only.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ */
+
+isc_result_t
+isc_task_beginexclusive(isc_task_t *task);
+/*%<
+ * Request exclusive access for 'task', which must be the calling
+ * task. Waits for any other concurrently executing tasks to finish their
+ * current event, and prevents any new events from executing in any of the
+ * tasks sharing a task manager with 'task'.
+ *
+ * The exclusive access must be relinquished by calling
+ * isc_task_endexclusive() before returning from the current event handler.
+ *
+ * Requires:
+ *\li 'task' is the calling task.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS The current task now has exclusive access.
+ *\li #ISC_R_LOCKBUSY Another task has already requested exclusive
+ * access.
+ */
+
+void
+isc_task_endexclusive(isc_task_t *task);
+/*%<
+ * Relinquish the exclusive access obtained by isc_task_beginexclusive(),
+ * allowing other tasks to execute.
+ *
+ * Requires:
+ *\li 'task' is the calling task, and has obtained
+ * exclusive access by calling isc_task_spl().
+ */
+
+void
+isc_task_getcurrenttime(isc_task_t *task, isc_stdtime_t *t);
+/*%<
+ * Provide the most recent timestamp on the task. The timestamp is considered
+ * as the "current time" in the second-order granularity.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ *\li 't' is a valid non NULL pointer.
+ *
+ * Ensures:
+ *\li '*t' has the "current time".
+ */
+
+isc_boolean_t
+isc_task_exiting(isc_task_t *t);
+/*%<
+ * Returns ISC_TRUE if the task is in the process of shutting down,
+ * ISC_FALSE otherwise.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ */
+
+void
+isc_task_setprivilege(isc_task_t *task, isc_boolean_t priv);
+/*%<
+ * Set or unset the task's "privileged" flag depending on the value of
+ * 'priv'.
+ *
+ * Under normal circumstances this flag has no effect on the task behavior,
+ * but when the task manager has been set to privileged exeuction mode via
+ * isc_taskmgr_setmode(), only tasks with the flag set will be executed,
+ * and all other tasks will wait until they're done. Once all privileged
+ * tasks have finished executing, the task manager will automatically
+ * return to normal execution mode and nonprivileged task can resume.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ */
+
+isc_boolean_t
+isc_task_privilege(isc_task_t *task);
+/*%<
+ * Returns the current value of the task's privilege flag.
+ *
+ * Requires:
+ *\li 'task' is a valid task.
+ */
+
+/*****
+ ***** Task Manager.
+ *****/
+
+isc_result_t
+isc_taskmgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ unsigned int workers, unsigned int default_quantum,
+ isc_taskmgr_t **managerp);
+isc_result_t
+isc_taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp);
+/*%<
+ * Create a new task manager. isc_taskmgr_createinctx() also associates
+ * the new manager with the specified application context.
+ *
+ * Notes:
+ *
+ *\li 'workers' in the number of worker threads to create. In general,
+ * the value should be close to the number of processors in the system.
+ * The 'workers' value is advisory only. An attempt will be made to
+ * create 'workers' threads, but if at least one thread creation
+ * succeeds, isc_taskmgr_create() may return ISC_R_SUCCESS.
+ *
+ *\li If 'default_quantum' is non-zero, then it will be used as the default
+ * quantum value when tasks are created. If zero, then an implementation
+ * defined default quantum will be used.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li workers > 0
+ *
+ *\li managerp != NULL && *managerp == NULL
+ *
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
+ * Ensures:
+ *
+ *\li On success, '*managerp' will be attached to the newly created task
+ * manager.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_NOTHREADS No threads could be created.
+ *\li #ISC_R_UNEXPECTED An unexpected error occurred.
+ *\li #ISC_R_SHUTTINGDOWN The non-threaded, shared, task
+ * manager shutting down.
+ */
+
+void
+isc_taskmgr_setmode(isc_taskmgr_t *manager, isc_taskmgrmode_t mode);
+
+isc_taskmgrmode_t
+isc_taskmgr_mode(isc_taskmgr_t *manager);
+/*%<
+ * Set/get the current operating mode of the task manager. Valid modes are:
+ *
+ *\li isc_taskmgrmode_normal
+ *\li isc_taskmgrmode_privileged
+ *
+ * In privileged execution mode, only tasks that have had the "privilege"
+ * flag set via isc_task_setprivilege() can be executed. When all such
+ * tasks are complete, the manager automatically returns to normal mode
+ * and proceeds with running non-privileged ready tasks. This means it is
+ * necessary to have at least one privileged task waiting on the ready
+ * queue *before* setting the manager into privileged execution mode,
+ * which in turn means the task which calls this function should be in
+ * task-exclusive mode when it does so.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid task manager.
+ */
+
+void
+isc_taskmgr_destroy(isc_taskmgr_t **managerp);
+/*%<
+ * Destroy '*managerp'.
+ *
+ * Notes:
+ *
+ *\li Calling isc_taskmgr_destroy() will shutdown all tasks managed by
+ * *managerp that haven't already been shutdown. The call will block
+ * until all tasks have entered the done state.
+ *
+ *\li isc_taskmgr_destroy() must not be called by a task event action,
+ * because it would block forever waiting for the event action to
+ * complete. An event action that wants to cause task manager shutdown
+ * should request some non-event action thread of execution to do the
+ * shutdown, e.g. by signaling a condition variable or using
+ * isc_app_shutdown().
+ *
+ *\li Task manager references are not reference counted, so the caller
+ * must ensure that no attempt will be made to use the manager after
+ * isc_taskmgr_destroy() returns.
+ *
+ * Requires:
+ *
+ *\li '*managerp' is a valid task manager.
+ *
+ *\li isc_taskmgr_destroy() has not be called previously on '*managerp'.
+ *
+ * Ensures:
+ *
+ *\li All resources used by the task manager, and any tasks it managed,
+ * have been freed.
+ */
+
+#ifdef HAVE_LIBXML2
+
+void
+isc_taskmgr_renderxml(isc_taskmgr_t *mgr, xmlTextWriterPtr writer);
+
+#endif
+
+/*%<
+ * See isc_taskmgr_create() above.
+ */
+typedef isc_result_t
+(*isc_taskmgrcreatefunc_t)(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum,
+ isc_taskmgr_t **managerp);
+
+isc_result_t
+isc_task_register(isc_taskmgrcreatefunc_t createfunc);
+/*%<
+ * Register a new task management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc__task_register(void);
+/*%<
+ * A short cut function that specifies the task management module in the ISC
+ * library for isc_task_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TASK_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/timer.h b/contrib/ntp/libntp/lib/isc/include/isc/timer.h
new file mode 100644
index 000000000000..fa9abb16aa9d
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/timer.h
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: timer.h,v 1.43 2009/09/02 23:48:03 tbox Exp $ */
+
+#ifndef ISC_TIMER_H
+#define ISC_TIMER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/timer.h
+ * \brief Provides timers which are event sources in the task system.
+ *
+ * Three types of timers are supported:
+ *
+ *\li 'ticker' timers generate a periodic tick event.
+ *
+ *\li 'once' timers generate an idle timeout event if they are idle for too
+ * long, and generate a life timeout event if their lifetime expires.
+ * They are used to implement both (possibly expiring) idle timers and
+ * 'one-shot' timers.
+ *
+ *\li 'limited' timers generate a periodic tick event until they reach
+ * their lifetime when they generate a life timeout event.
+ *
+ *\li 'inactive' timers generate no events.
+ *
+ * Timers can change type. It is typical to create a timer as
+ * an 'inactive' timer and then change it into a 'ticker' or
+ * 'once' timer.
+ *
+ *\li MP:
+ * The module ensures appropriate synchronization of data structures it
+ * creates and manipulates.
+ * Clients of this module must not be holding a timer's task's lock when
+ * making a call that affects that timer. Failure to follow this rule
+ * can result in deadlock.
+ * The caller must ensure that isc_timermgr_destroy() is called only
+ * once for a given manager.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/types.h>
+#include <isc/event.h>
+#include <isc/eventclass.h>
+#include <isc/lang.h>
+#include <isc/time.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+/*% Timer Type */
+typedef enum {
+ isc_timertype_ticker = 0, /*%< Ticker */
+ isc_timertype_once = 1, /*%< Once */
+ isc_timertype_limited = 2, /*%< Limited */
+ isc_timertype_inactive = 3 /*%< Inactive */
+} isc_timertype_t;
+
+typedef struct isc_timerevent {
+ struct isc_event common;
+ isc_time_t due;
+} isc_timerevent_t;
+
+#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0)
+#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1)
+#define ISC_TIMEREVENT_IDLE (ISC_EVENTCLASS_TIMER + 2)
+#define ISC_TIMEREVENT_LIFE (ISC_EVENTCLASS_TIMER + 3)
+#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535)
+
+/*% Timer and timer manager methods */
+typedef struct {
+ void (*destroy)(isc_timermgr_t **managerp);
+ isc_result_t (*timercreate)(isc_timermgr_t *manager,
+ isc_timertype_t type,
+ isc_time_t *expires,
+ isc_interval_t *interval,
+ isc_task_t *task,
+ isc_taskaction_t action,
+ const void *arg,
+ isc_timer_t **timerp);
+} isc_timermgrmethods_t;
+
+typedef struct {
+ void (*attach)(isc_timer_t *timer, isc_timer_t **timerp);
+ void (*detach)(isc_timer_t **timerp);
+ isc_result_t (*reset)(isc_timer_t *timer, isc_timertype_t type,
+ isc_time_t *expires, isc_interval_t *interval,
+ isc_boolean_t purge);
+ isc_result_t (*touch)(isc_timer_t *timer);
+} isc_timermethods_t;
+
+/*%
+ * This structure is actually just the common prefix of a timer manager
+ * object implementation's version of an isc_timermgr_t.
+ * \brief
+ * Direct use of this structure by clients is forbidden. timer implementations
+ * may change the structure. 'magic' must be ISCAPI_TIMERMGR_MAGIC for any
+ * of the isc_timer_ routines to work. timer implementations must maintain
+ * all timer invariants.
+ */
+struct isc_timermgr {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_timermgrmethods_t *methods;
+};
+
+#define ISCAPI_TIMERMGR_MAGIC ISC_MAGIC('A','t','m','g')
+#define ISCAPI_TIMERMGR_VALID(m) ((m) != NULL && \
+ (m)->magic == ISCAPI_TIMERMGR_MAGIC)
+
+/*%
+ * This is the common prefix of a timer object. The same note as
+ * that for the timermgr structure applies.
+ */
+struct isc_timer {
+ unsigned int impmagic;
+ unsigned int magic;
+ isc_timermethods_t *methods;
+};
+
+#define ISCAPI_TIMER_MAGIC ISC_MAGIC('A','t','m','r')
+#define ISCAPI_TIMER_VALID(s) ((s) != NULL && \
+ (s)->magic == ISCAPI_TIMER_MAGIC)
+
+/***
+ *** Timer and Timer Manager Functions
+ ***
+ *** Note: all Ensures conditions apply only if the result is success for
+ *** those functions which return an isc_result_t.
+ ***/
+
+isc_result_t
+isc_timer_create(isc_timermgr_t *manager,
+ isc_timertype_t type,
+ isc_time_t *expires,
+ isc_interval_t *interval,
+ isc_task_t *task,
+ isc_taskaction_t action,
+ const void *arg,
+ isc_timer_t **timerp);
+/*%<
+ * Create a new 'type' timer managed by 'manager'. The timers parameters
+ * are specified by 'expires' and 'interval'. Events will be posted to
+ * 'task' and when dispatched 'action' will be called with 'arg' as the
+ * arg value. The new timer is returned in 'timerp'.
+ *
+ * Notes:
+ *
+ *\li For ticker timers, the timer will generate a 'tick' event every
+ * 'interval' seconds. The value of 'expires' is ignored.
+ *
+ *\li For once timers, 'expires' specifies the time when a life timeout
+ * event should be generated. If 'expires' is 0 (the epoch), then no life
+ * timeout will be generated. 'interval' specifies how long the timer
+ * can be idle before it generates an idle timeout. If 0, then no
+ * idle timeout will be generated.
+ *
+ *\li If 'expires' is NULL, the epoch will be used.
+ *
+ * If 'interval' is NULL, the zero interval will be used.
+ *
+ * Requires:
+ *
+ *\li 'manager' is a valid manager
+ *
+ *\li 'task' is a valid task
+ *
+ *\li 'action' is a valid action
+ *
+ *\li 'expires' points to a valid time, or is NULL.
+ *
+ *\li 'interval' points to a valid interval, or is NULL.
+ *
+ *\li type == isc_timertype_inactive ||
+ * ('expires' and 'interval' are not both 0)
+ *
+ *\li 'timerp' is a valid pointer, and *timerp == NULL
+ *
+ * Ensures:
+ *
+ *\li '*timerp' is attached to the newly created timer
+ *
+ *\li The timer is attached to the task
+ *
+ *\li An idle timeout will not be generated until at least Now + the
+ * timer's interval if 'timer' is a once timer with a non-zero
+ * interval.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li No memory
+ *\li Unexpected error
+ */
+
+isc_result_t
+isc_timer_reset(isc_timer_t *timer,
+ isc_timertype_t type,
+ isc_time_t *expires,
+ isc_interval_t *interval,
+ isc_boolean_t purge);
+/*%<
+ * Change the timer's type, expires, and interval values to the given
+ * values. If 'purge' is TRUE, any pending events from this timer
+ * are purged from its task's event queue.
+ *
+ * Notes:
+ *
+ *\li If 'expires' is NULL, the epoch will be used.
+ *
+ *\li If 'interval' is NULL, the zero interval will be used.
+ *
+ * Requires:
+ *
+ *\li 'timer' is a valid timer
+ *
+ *\li The same requirements that isc_timer_create() imposes on 'type',
+ * 'expires' and 'interval' apply.
+ *
+ * Ensures:
+ *
+ *\li An idle timeout will not be generated until at least Now + the
+ * timer's interval if 'timer' is a once timer with a non-zero
+ * interval.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li No memory
+ *\li Unexpected error
+ */
+
+isc_result_t
+isc_timer_touch(isc_timer_t *timer);
+/*%<
+ * Set the last-touched time of 'timer' to the current time.
+ *
+ * Requires:
+ *
+ *\li 'timer' is a valid once timer.
+ *
+ * Ensures:
+ *
+ *\li An idle timeout will not be generated until at least Now + the
+ * timer's interval if 'timer' is a once timer with a non-zero
+ * interval.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li Unexpected error
+ */
+
+void
+isc_timer_attach(isc_timer_t *timer, isc_timer_t **timerp);
+/*%<
+ * Attach *timerp to timer.
+ *
+ * Requires:
+ *
+ *\li 'timer' is a valid timer.
+ *
+ *\li 'timerp' points to a NULL timer.
+ *
+ * Ensures:
+ *
+ *\li *timerp is attached to timer.
+ */
+
+void
+isc_timer_detach(isc_timer_t **timerp);
+/*%<
+ * Detach *timerp from its timer.
+ *
+ * Requires:
+ *
+ *\li 'timerp' points to a valid timer.
+ *
+ * Ensures:
+ *
+ *\li *timerp is NULL.
+ *
+ *\li If '*timerp' is the last reference to the timer,
+ * then:
+ *
+ *\code
+ * The timer will be shutdown
+ *
+ * The timer will detach from its task
+ *
+ * All resources used by the timer have been freed
+ *
+ * Any events already posted by the timer will be purged.
+ * Therefore, if isc_timer_detach() is called in the context
+ * of the timer's task, it is guaranteed that no more
+ * timer event callbacks will run after the call.
+ *\endcode
+ */
+
+isc_timertype_t
+isc_timer_gettype(isc_timer_t *timer);
+/*%<
+ * Return the timer type.
+ *
+ * Requires:
+ *
+ *\li 'timer' to be a valid timer.
+ */
+
+isc_result_t
+isc_timermgr_createinctx(isc_mem_t *mctx, isc_appctx_t *actx,
+ isc_timermgr_t **managerp);
+
+isc_result_t
+isc_timermgr_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
+/*%<
+ * Create a timer manager. isc_timermgr_createinctx() also associates
+ * the new manager with the specified application context.
+ *
+ * Notes:
+ *
+ *\li All memory will be allocated in memory context 'mctx'.
+ *
+ * Requires:
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li 'managerp' points to a NULL isc_timermgr_t.
+ *
+ *\li 'actx' is a valid application context (for createinctx()).
+ *
+ * Ensures:
+ *
+ *\li '*managerp' is a valid isc_timermgr_t.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li No memory
+ *\li Unexpected error
+ */
+
+void
+isc_timermgr_destroy(isc_timermgr_t **managerp);
+/*%<
+ * Destroy a timer manager.
+ *
+ * Notes:
+ *
+ *\li This routine blocks until there are no timers left in the manager,
+ * so if the caller holds any timer references using the manager, it
+ * must detach them before calling isc_timermgr_destroy() or it will
+ * block forever.
+ *
+ * Requires:
+ *
+ *\li '*managerp' is a valid isc_timermgr_t.
+ *
+ * Ensures:
+ *
+ *\li *managerp == NULL
+ *
+ *\li All resources used by the manager have been freed.
+ */
+
+void isc_timermgr_poke(isc_timermgr_t *m);
+
+#ifdef USE_TIMERIMPREGISTER
+/*%<
+ * See isc_timermgr_create() above.
+ */
+typedef isc_result_t
+(*isc_timermgrcreatefunc_t)(isc_mem_t *mctx, isc_timermgr_t **managerp);
+
+isc_result_t
+isc__timer_register(void);
+/*%<
+ * Register a new timer management implementation and add it to the list of
+ * supported implementations. This function must be called when a different
+ * event library is used than the one contained in the ISC library.
+ */
+
+isc_result_t
+isc_timer_register(isc_timermgrcreatefunc_t createfunc);
+/*%<
+ * A short cut function that specifies the timer management module in the ISC
+ * library for isc_timer_register(). An application that uses the ISC library
+ * usually do not have to care about this function: it would call
+ * isc_lib_register(), which internally calls this function.
+ */
+#endif /* USE_TIMERIMPREGISTER */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TIMER_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/types.h b/contrib/ntp/libntp/lib/isc/include/isc/types.h
new file mode 100644
index 000000000000..8dbf67ed109e
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/types.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2004-2009, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_TYPES_H
+#define ISC_TYPES_H 1
+
+#include <isc/bind9.h>
+#include <isc/namespace.h>
+
+/*! \file isc/types.h
+ * \brief
+ * OS-specific types, from the OS-specific include directories.
+ */
+#include <isc/int.h>
+#include <isc/offset.h>
+
+/*
+ * XXXDCL should isc_boolean_t be moved here, requiring an explicit include
+ * of <isc/boolean.h> when ISC_TRUE/ISC_FALSE/ISC_TF() are desired?
+ */
+#include <isc/boolean.h>
+/*
+ * XXXDCL This is just for ISC_LIST and ISC_LINK, but gets all of the other
+ * list macros too.
+ */
+#include <isc/list.h>
+
+/* Core Types. Alphabetized by defined type. */
+
+typedef struct isc_appctx isc_appctx_t; /*%< Application context */
+typedef struct isc_backtrace_symmap isc_backtrace_symmap_t; /*%< Symbol Table Entry */
+typedef struct isc_bitstring isc_bitstring_t; /*%< Bitstring */
+typedef struct isc_buffer isc_buffer_t; /*%< Buffer */
+typedef ISC_LIST(isc_buffer_t) isc_bufferlist_t; /*%< Buffer List */
+typedef struct isc_constregion isc_constregion_t; /*%< Const region */
+typedef struct isc_consttextregion isc_consttextregion_t; /*%< Const Text Region */
+typedef struct isc_entropy isc_entropy_t; /*%< Entropy */
+typedef struct isc_entropysource isc_entropysource_t; /*%< Entropy Source */
+typedef struct isc_event isc_event_t; /*%< Event */
+typedef ISC_LIST(isc_event_t) isc_eventlist_t; /*%< Event List */
+typedef unsigned int isc_eventtype_t; /*%< Event Type */
+typedef isc_uint32_t isc_fsaccess_t; /*%< FS Access */
+typedef struct isc_hash isc_hash_t; /*%< Hash */
+typedef struct isc_httpd isc_httpd_t; /*%< HTTP client */
+typedef void (isc_httpdfree_t)(isc_buffer_t *, void *); /*%< HTTP free function */
+typedef struct isc_httpdmgr isc_httpdmgr_t; /*%< HTTP manager */
+typedef struct isc_httpdurl isc_httpdurl_t; /*%< HTTP URL */
+typedef void (isc_httpdondestroy_t)(void *); /*%< Callback on destroying httpd */
+typedef struct isc_interface isc_interface_t; /*%< Interface */
+typedef struct isc_interfaceiter isc_interfaceiter_t; /*%< Interface Iterator */
+typedef struct isc_interval isc_interval_t; /*%< Interval */
+typedef struct isc_lex isc_lex_t; /*%< Lex */
+typedef struct isc_log isc_log_t; /*%< Log */
+typedef struct isc_logcategory isc_logcategory_t; /*%< Log Category */
+typedef struct isc_logconfig isc_logconfig_t; /*%< Log Configuration */
+typedef struct isc_logmodule isc_logmodule_t; /*%< Log Module */
+typedef struct isc_mem isc_mem_t; /*%< Memory */
+typedef struct isc_mempool isc_mempool_t; /*%< Memory Pool */
+typedef struct isc_msgcat isc_msgcat_t; /*%< Message Catalog */
+typedef struct isc_ondestroy isc_ondestroy_t; /*%< On Destroy */
+typedef struct isc_netaddr isc_netaddr_t; /*%< Net Address */
+typedef struct isc_portset isc_portset_t; /*%< Port Set */
+typedef struct isc_quota isc_quota_t; /*%< Quota */
+typedef struct isc_random isc_random_t; /*%< Random */
+typedef struct isc_ratelimiter isc_ratelimiter_t; /*%< Rate Limiter */
+typedef struct isc_region isc_region_t; /*%< Region */
+typedef isc_uint64_t isc_resourcevalue_t; /*%< Resource Value */
+typedef unsigned int isc_result_t; /*%< Result */
+typedef struct isc_rwlock isc_rwlock_t; /*%< Read Write Lock */
+typedef struct isc_sockaddr isc_sockaddr_t; /*%< Socket Address */
+typedef struct isc_socket isc_socket_t; /*%< Socket */
+typedef struct isc_socketevent isc_socketevent_t; /*%< Socket Event */
+typedef struct isc_socketmgr isc_socketmgr_t; /*%< Socket Manager */
+typedef struct isc_stats isc_stats_t; /*%< Statistics */
+typedef int isc_statscounter_t; /*%< Statistics Counter */
+typedef struct isc_symtab isc_symtab_t; /*%< Symbol Table */
+typedef struct isc_task isc_task_t; /*%< Task */
+typedef ISC_LIST(isc_task_t) isc_tasklist_t; /*%< Task List */
+typedef struct isc_taskmgr isc_taskmgr_t; /*%< Task Manager */
+typedef struct isc_textregion isc_textregion_t; /*%< Text Region */
+typedef struct isc_time isc_time_t; /*%< Time */
+typedef struct isc_timer isc_timer_t; /*%< Timer */
+typedef struct isc_timermgr isc_timermgr_t; /*%< Timer Manager */
+
+typedef void (*isc_taskaction_t)(isc_task_t *, isc_event_t *);
+typedef int (*isc_sockfdwatch_t)(isc_task_t *, isc_socket_t *, void *, int);
+
+/* The following cannot be listed alphabetically due to forward reference */
+typedef isc_result_t (isc_httpdaction_t)(const char *url,
+ const char *querystring,
+ void *arg,
+ unsigned int *retcode,
+ const char **retmsg,
+ const char **mimetype,
+ isc_buffer_t *body,
+ isc_httpdfree_t **freecb,
+ void **freecb_args);
+typedef isc_boolean_t (isc_httpdclientok_t)(const isc_sockaddr_t *, void *);
+
+/*% Resource */
+typedef enum {
+ isc_resource_coresize = 1,
+ isc_resource_cputime,
+ isc_resource_datasize,
+ isc_resource_filesize,
+ isc_resource_lockedmemory,
+ isc_resource_openfiles,
+ isc_resource_processes,
+ isc_resource_residentsize,
+ isc_resource_stacksize
+} isc_resource_t;
+
+#endif /* ISC_TYPES_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/util.h b/contrib/ntp/libntp/lib/isc/include/isc/util.h
new file mode 100644
index 000000000000..670b28bc4c01
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/util.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2004-2007, 2010-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_UTIL_H
+#define ISC_UTIL_H 1
+
+/*! \file isc/util.h
+ * NOTE:
+ *
+ * This file is not to be included from any <isc/???.h> (or other) library
+ * files.
+ *
+ * \brief
+ * Including this file puts several macros in your name space that are
+ * not protected (as all the other ISC functions/macros do) by prepending
+ * ISC_ or isc_ to the name.
+ */
+
+/***
+ *** General Macros.
+ ***/
+
+/*%
+ * Use this to hide unused function arguments.
+ * \code
+ * int
+ * foo(char *bar)
+ * {
+ * UNUSED(bar);
+ * }
+ * \endcode
+ */
+#define UNUSED(x) (void)(x)
+
+/*%
+ * The opposite: silent warnings about stored values which are never read.
+ */
+#define POST(x) (void)(x)
+
+#define ISC_MAX(a, b) ((a) > (b) ? (a) : (b))
+#define ISC_MIN(a, b) ((a) < (b) ? (a) : (b))
+
+/*%
+ * Use this to remove the const qualifier of a variable to assign it to
+ * a non-const variable or pass it as a non-const function argument ...
+ * but only when you are sure it won't then be changed!
+ * This is necessary to sometimes shut up some compilers
+ * (as with gcc -Wcast-qual) when there is just no other good way to avoid the
+ * situation.
+ */
+#define DE_CONST(konst, var) \
+ do { \
+ union { const void *k; void *v; } _u; \
+ _u.k = konst; \
+ var = _u.v; \
+ } while (0)
+
+/*%
+ * Use this in translation units that would otherwise be empty, to
+ * suppress compiler warnings.
+ */
+#define EMPTY_TRANSLATION_UNIT extern void exit(int);
+
+/*%
+ * We use macros instead of calling the routines directly because
+ * the capital letters make the locking stand out.
+ * We RUNTIME_CHECK for success since in general there's no way
+ * for us to continue if they fail.
+ */
+
+#ifdef ISC_UTIL_TRACEON
+#define ISC_UTIL_TRACE(a) a
+#include <stdio.h> /* Required for fprintf/stderr when tracing. */
+#include <isc/msgs.h> /* Required for isc_msgcat when tracing. */
+#else
+#define ISC_UTIL_TRACE(a)
+#endif
+
+#include <isc/result.h> /* Contractual promise. */
+
+#define LOCK(lp) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_LOCKING, "LOCKING"), \
+ (lp), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_mutex_lock((lp)) == ISC_R_SUCCESS); \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_LOCKED, "LOCKED"), \
+ (lp), __FILE__, __LINE__)); \
+ } while (0)
+#define UNLOCK(lp) do { \
+ RUNTIME_CHECK(isc_mutex_unlock((lp)) == ISC_R_SUCCESS); \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_UNLOCKED, "UNLOCKED"), \
+ (lp), __FILE__, __LINE__)); \
+ } while (0)
+#define ISLOCKED(lp) (1)
+#define DESTROYLOCK(lp) \
+ RUNTIME_CHECK(isc_mutex_destroy((lp)) == ISC_R_SUCCESS)
+
+
+#define BROADCAST(cvp) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_BROADCAST, "BROADCAST"),\
+ (cvp), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_condition_broadcast((cvp)) == ISC_R_SUCCESS); \
+ } while (0)
+#define SIGNAL(cvp) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_SIGNAL, "SIGNAL"), \
+ (cvp), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_condition_signal((cvp)) == ISC_R_SUCCESS); \
+ } while (0)
+#define WAIT(cvp, lp) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_UTILWAIT, "WAIT"), \
+ (cvp), \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_LOCK, "LOCK"), \
+ (lp), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_condition_wait((cvp), (lp)) == ISC_R_SUCCESS); \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p %s %p %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_WAITED, "WAITED"), \
+ (cvp), \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_LOCKED, "LOCKED"), \
+ (lp), __FILE__, __LINE__)); \
+ } while (0)
+
+/*
+ * isc_condition_waituntil can return ISC_R_TIMEDOUT, so we
+ * don't RUNTIME_CHECK the result.
+ *
+ * XXX Also, can't really debug this then...
+ */
+
+#define WAITUNTIL(cvp, lp, tp) \
+ isc_condition_waituntil((cvp), (lp), (tp))
+
+#define RWLOCK(lp, t) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_RWLOCK, "RWLOCK"), \
+ (lp), (t), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_rwlock_lock((lp), (t)) == ISC_R_SUCCESS); \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_RWLOCKED, "RWLOCKED"), \
+ (lp), (t), __FILE__, __LINE__)); \
+ } while (0)
+#define RWUNLOCK(lp, t) do { \
+ ISC_UTIL_TRACE(fprintf(stderr, "%s %p, %d %s %d\n", \
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_UTIL, \
+ ISC_MSG_RWUNLOCK, "RWUNLOCK"), \
+ (lp), (t), __FILE__, __LINE__)); \
+ RUNTIME_CHECK(isc_rwlock_unlock((lp), (t)) == ISC_R_SUCCESS); \
+ } while (0)
+
+#define DESTROYMUTEXBLOCK(bp, n) \
+ RUNTIME_CHECK(isc_mutexblock_destroy((bp), (n)) == ISC_R_SUCCESS)
+
+/*
+ * List Macros.
+ */
+#include <isc/list.h> /* Contractual promise. */
+
+#define LIST(type) ISC_LIST(type)
+#define INIT_LIST(type) ISC_LIST_INIT(type)
+#define LINK(type) ISC_LINK(type)
+#define INIT_LINK(elt, link) ISC_LINK_INIT(elt, link)
+#define HEAD(list) ISC_LIST_HEAD(list)
+#define TAIL(list) ISC_LIST_TAIL(list)
+#define EMPTY(list) ISC_LIST_EMPTY(list)
+#define PREV(elt, link) ISC_LIST_PREV(elt, link)
+#define NEXT(elt, link) ISC_LIST_NEXT(elt, link)
+#define APPEND(list, elt, link) ISC_LIST_APPEND(list, elt, link)
+#define PREPEND(list, elt, link) ISC_LIST_PREPEND(list, elt, link)
+#define UNLINK(list, elt, link) ISC_LIST_UNLINK(list, elt, link)
+#define ENQUEUE(list, elt, link) ISC_LIST_APPEND(list, elt, link)
+#define DEQUEUE(list, elt, link) ISC_LIST_UNLINK(list, elt, link)
+#define INSERTBEFORE(li, b, e, ln) ISC_LIST_INSERTBEFORE(li, b, e, ln)
+#define INSERTAFTER(li, a, e, ln) ISC_LIST_INSERTAFTER(li, a, e, ln)
+#define APPENDLIST(list1, list2, link) ISC_LIST_APPENDLIST(list1, list2, link)
+
+/*
+ * Assertions
+ */
+#include <isc/assertions.h> /* Contractual promise. */
+
+/*% Require Assertion */
+#define REQUIRE(e) ISC_REQUIRE(e)
+/*% Ensure Assertion */
+#define ENSURE(e) ISC_ENSURE(e)
+/*% Insist Assertion */
+#define INSIST(e) ISC_INSIST(e)
+/*% Invariant Assertion */
+#define INVARIANT(e) ISC_INVARIANT(e)
+
+/*
+ * Errors
+ */
+#include <isc/error.h> /* Contractual promise. */
+
+/*% Unexpected Error */
+#define UNEXPECTED_ERROR isc_error_unexpected
+/*% Fatal Error */
+#define FATAL_ERROR isc_error_fatal
+/*% Runtime Check */
+#define RUNTIME_CHECK(cond) ISC_ERROR_RUNTIMECHECK(cond)
+
+/*%
+ * Time
+ */
+#define TIME_NOW(tp) RUNTIME_CHECK(isc_time_now((tp)) == ISC_R_SUCCESS)
+
+#endif /* ISC_UTIL_H */
diff --git a/contrib/ntp/libntp/lib/isc/include/isc/xml.h b/contrib/ntp/libntp/lib/isc/include/isc/xml.h
new file mode 100644
index 000000000000..d31a31a7f0d5
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/include/isc/xml.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: xml.h,v 1.4 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_XML_H
+#define ISC_XML_H 1
+
+/*
+ * This file is here mostly to make it easy to add additional libxml header
+ * files as needed across all the users of this file. Rather than place
+ * these libxml includes in each file, one include makes it easy to handle
+ * the ifdef as well as adding the ability to add additional functions
+ * which may be useful.
+ */
+
+#ifdef HAVE_LIBXML2
+#include <libxml/encoding.h>
+#include <libxml/xmlwriter.h>
+#endif
+
+#define ISC_XMLCHAR (const xmlChar *)
+
+#define ISC_XML_RENDERCONFIG 0x00000001 /* render config data */
+#define ISC_XML_RENDERSTATS 0x00000002 /* render stats */
+#define ISC_XML_RENDERALL 0x000000ff /* render everything */
+
+#endif /* ISC_XML_H */
diff --git a/contrib/ntp/libntp/lib/isc/inet_ntop.c b/contrib/ntp/libntp/lib/isc/inet_ntop.c
new file mode 100644
index 000000000000..773018031b9d
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/inet_ntop.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1996-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*! \file */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] =
+ "$Id: inet_ntop.c,v 1.21 2009/07/17 23:47:41 tbox Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/net.h>
+#include <isc/print.h>
+
+#define NS_INT16SZ 2
+#define NS_IN6ADDRSZ 16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static const char *inet_ntop4(const unsigned char *src, char *dst,
+ size_t size);
+
+#ifdef AF_INET6
+static const char *inet_ntop6(const unsigned char *src, char *dst,
+ size_t size);
+#endif
+const char *isc_net_ntop(int af, const void *src, char *dst, size_t size);
+
+/*! char *
+ * isc_net_ntop(af, src, dst, size)
+ * convert a network format address to presentation format.
+ * \return
+ * pointer to presentation format address (`dst'), or NULL (see errno).
+ * \author
+ * Paul Vixie, 1996.
+ */
+const char *
+isc_net_ntop(int af, const void *src, char *dst, size_t size)
+{
+ switch (af) {
+ case AF_INET:
+ return (inet_ntop4(src, dst, size));
+#ifdef AF_INET6
+ case AF_INET6:
+ return (inet_ntop6(src, dst, size));
+#endif
+ default:
+ errno = EAFNOSUPPORT;
+ return (NULL);
+ }
+ /* NOTREACHED */
+}
+
+/*! const char *
+ * inet_ntop4(src, dst, size)
+ * format an IPv4 address
+ * \return
+ * `dst' (as a const)
+ * \note
+ * (1) uses no statics
+ * \note
+ * (2) takes a unsigned char* not an in_addr as input
+ * \author
+ * Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(const unsigned char *src, char *dst, size_t size)
+{
+ static const char *fmt = "%u.%u.%u.%u";
+ char tmp[sizeof("255.255.255.255")];
+ int len;
+
+ len = snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]);
+ if (len < 0 || (size_t)len >= size)
+ {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ memcpy(dst, tmp, 1 + len);
+
+ return (dst);
+}
+
+/*! const char *
+ * isc_inet_ntop6(src, dst, size)
+ * convert IPv6 binary address into presentation (printable) format
+ * \author
+ * Paul Vixie, 1996.
+ */
+#ifdef AF_INET6
+static const char *
+inet_ntop6(const unsigned char *src, char *dst, size_t size)
+{
+ /*
+ * Note that int32_t and int16_t need only be "at least" large enough
+ * to contain a value of the specified size. On some systems, like
+ * Crays, there is no such thing as an integer variable with 16 bits.
+ * Keep this in mind if you think this function should have been coded
+ * to use pointer overlays. All the world's not a VAX.
+ */
+ char tmp[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")], *tp;
+ struct { int base, len; } best, cur;
+ unsigned int words[NS_IN6ADDRSZ / NS_INT16SZ];
+ int i;
+
+ /*
+ * Preprocess:
+ * Copy the input (bytewise) array into a wordwise array.
+ * Find the longest run of 0x00's in src[] for :: shorthanding.
+ */
+ memset(words, '\0', sizeof(words));
+ for (i = 0; i < NS_IN6ADDRSZ; i++)
+ words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
+ best.base = -1;
+ cur.base = -1;
+ best.len = cur.len = 0;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ if (words[i] == 0) {
+ if (cur.base == -1)
+ cur.base = i, cur.len = 1;
+ else
+ cur.len++;
+ } else {
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ cur.base = -1;
+ }
+ }
+ }
+ if (cur.base != -1) {
+ if (best.base == -1 || cur.len > best.len)
+ best = cur;
+ }
+ if (best.base != -1 && best.len < 2)
+ best.base = -1;
+
+ /*
+ * Format the result.
+ */
+ tp = tmp;
+ for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+ /* Are we inside the best run of 0x00's? */
+ if (best.base != -1 && i >= best.base &&
+ i < (best.base + best.len)) {
+ if (i == best.base)
+ *tp++ = ':';
+ continue;
+ }
+ /* Are we following an initial run of 0x00s or any real hex? */
+ if (i != 0)
+ *tp++ = ':';
+ /* Is this address an encapsulated IPv4? */
+ if (i == 6 && best.base == 0 && (best.len == 6 ||
+ (best.len == 7 && words[7] != 0x0001) ||
+ (best.len == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp,
+ sizeof(tmp) - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ tp += snprintf(tp, sizeof(tmp) - (tp - tmp), "%x", words[i]);
+ }
+ /* Was it a trailing run of 0x00's? */
+ if (best.base != -1 && (best.base + best.len) ==
+ (NS_IN6ADDRSZ / NS_INT16SZ))
+ *tp++ = ':';
+ *tp++ = '\0';
+
+ /*
+ * Check for overflow, copy, and we're done.
+ */
+ if ((size_t)(tp - tmp) > size) {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ memcpy(dst, tmp, (size_t)(tp - tmp));
+ return (dst);
+}
+#endif /* AF_INET6 */
diff --git a/contrib/ntp/libntp/lib/isc/inet_pton.c b/contrib/ntp/libntp/lib/isc/inet_pton.c
new file mode 100644
index 000000000000..7e0766726664
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/inet_pton.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1996-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*! \file */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] =
+ "$Id: inet_pton.c,v 1.19 2007/06/19 23:47:17 tbox Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include <isc/net.h>
+
+/*% INT16 Size */
+#define NS_INT16SZ 2
+/*% IPv4 Address Size */
+#define NS_INADDRSZ 4
+/*% IPv6 Address Size */
+#define NS_IN6ADDRSZ 16
+
+/*
+ * WARNING: Don't even consider trying to compile this on a system where
+ * sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
+ */
+
+static int inet_pton4(const char *src, unsigned char *dst);
+static int inet_pton6(const char *src, unsigned char *dst);
+int isc_net_pton(int af, const char *src, void *dst);
+
+/*%
+ * convert from presentation format (which usually means ASCII printable)
+ * to network format (which is usually some kind of binary format).
+ * \return
+ * 1 if the address was valid for the specified address family
+ * 0 if the address wasn't valid (`dst' is untouched in this case)
+ * -1 if some other error occurred (`dst' is untouched in this case, too)
+ * \author
+ * Paul Vixie, 1996.
+ */
+int
+isc_net_pton(int af, const char *src, void *dst) {
+ switch (af) {
+ case AF_INET:
+ return (inet_pton4(src, dst));
+ case AF_INET6:
+ return (inet_pton6(src, dst));
+ default:
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+ /* NOTREACHED */
+}
+
+/*!\fn static int inet_pton4(const char *src, unsigned char *dst)
+ * \brief
+ * like inet_aton() but without all the hexadecimal and shorthand.
+ * \return
+ * 1 if `src' is a valid dotted quad, else 0.
+ * \note
+ * does not touch `dst' unless it's returning 1.
+ * \author
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton4(const char *src, unsigned char *dst) {
+ static const char digits[] = "0123456789";
+ int saw_digit, octets, ch;
+ unsigned char tmp[NS_INADDRSZ], *tp;
+
+ saw_digit = 0;
+ octets = 0;
+ *(tp = tmp) = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr(digits, ch)) != NULL) {
+ size_t newv = *tp * 10 + (pch - digits);
+
+ if (saw_digit && *tp == 0)
+ return (0);
+ if (newv > 255)
+ return (0);
+ *tp = (unsigned char)newv;
+ if (!saw_digit) {
+ if (++octets > 4)
+ return (0);
+ saw_digit = 1;
+ }
+ } else if (ch == '.' && saw_digit) {
+ if (octets == 4)
+ return (0);
+ *++tp = 0;
+ saw_digit = 0;
+ } else
+ return (0);
+ }
+ if (octets < 4)
+ return (0);
+ memcpy(dst, tmp, NS_INADDRSZ);
+ return (1);
+}
+
+/*%
+ * convert presentation level address to network order binary form.
+ * \return
+ * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * \note
+ * (1) does not touch `dst' unless it's returning 1.
+ * \note
+ * (2) :: in a full address is silently ignored.
+ * \author
+ * inspired by Mark Andrews.
+ * \author
+ * Paul Vixie, 1996.
+ */
+static int
+inet_pton6(const char *src, unsigned char *dst) {
+ static const char xdigits_l[] = "0123456789abcdef",
+ xdigits_u[] = "0123456789ABCDEF";
+ unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+ const char *xdigits, *curtok;
+ int ch, seen_xdigits;
+ unsigned int val;
+
+ memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+ endp = tp + NS_IN6ADDRSZ;
+ colonp = NULL;
+ /* Leading :: requires some special handling. */
+ if (*src == ':')
+ if (*++src != ':')
+ return (0);
+ curtok = src;
+ seen_xdigits = 0;
+ val = 0;
+ while ((ch = *src++) != '\0') {
+ const char *pch;
+
+ if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
+ pch = strchr((xdigits = xdigits_u), ch);
+ if (pch != NULL) {
+ val <<= 4;
+ val |= (pch - xdigits);
+ if (++seen_xdigits > 4)
+ return (0);
+ continue;
+ }
+ if (ch == ':') {
+ curtok = src;
+ if (!seen_xdigits) {
+ if (colonp)
+ return (0);
+ colonp = tp;
+ continue;
+ }
+ if (NS_INT16SZ > endp - tp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ seen_xdigits = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && (NS_INADDRSZ <= endp - tp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ seen_xdigits = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (seen_xdigits) {
+ if (NS_INT16SZ > endp - tp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ }
+ if (colonp != NULL) {
+ /*
+ * Since some memmove()'s erroneously fail to handle
+ * overlapping regions, we'll do the shift by hand.
+ */
+ const size_t n = tp - colonp;
+ int i;
+
+ if (tp == endp)
+ return (0);
+ for (i = 1; (size_t)i <= n; i++) {
+ endp[- i] = colonp[n - i];
+ colonp[n - i] = 0;
+ }
+ tp = endp;
+ }
+ if (tp != endp)
+ return (0);
+ memcpy(dst, tmp, NS_IN6ADDRSZ);
+ return (1);
+}
diff --git a/contrib/ntp/libntp/lib/isc/lib.c b/contrib/ntp/libntp/lib/isc/lib.c
new file mode 100644
index 000000000000..a50542551df3
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/lib.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: lib.c,v 1.16 2009/09/02 23:48:02 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <isc/app.h>
+#include <isc/lib.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/once.h>
+#include <isc/socket.h>
+#include <isc/task.h>
+#include <isc/timer.h>
+#include <isc/util.h>
+
+/***
+ *** Globals
+ ***/
+
+LIBISC_EXTERNAL_DATA isc_msgcat_t * isc_msgcat = NULL;
+
+
+/***
+ *** Private
+ ***/
+
+static isc_once_t msgcat_once = ISC_ONCE_INIT;
+
+/***
+ *** Functions
+ ***/
+
+static void
+open_msgcat(void) {
+ isc_msgcat_open("libisc.cat", &isc_msgcat);
+}
+
+void
+isc_lib_initmsgcat(void) {
+ isc_result_t result;
+
+ /*!
+ * Initialize the ISC library's message catalog, isc_msgcat, if it
+ * has not already been initialized.
+ */
+
+ result = isc_once_do(&msgcat_once, open_msgcat);
+ if (result != ISC_R_SUCCESS) {
+ /*
+ * Normally we'd use RUNTIME_CHECK() or FATAL_ERROR(), but
+ * we can't do that here, since they might call us!
+ * (Note that the catalog might be open anyway, so we might
+ * as well try to provide an internationalized message.)
+ */
+ fprintf(stderr, "%s:%d: %s: isc_once_do() %s.\n",
+ __FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FATALERROR, "fatal error"),
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+ abort();
+ }
+}
+
+#ifndef BIND9
+static isc_once_t register_once = ISC_ONCE_INIT;
+
+static void
+do_register(void) {
+ RUNTIME_CHECK(isc__mem_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__app_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__task_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__socket_register() == ISC_R_SUCCESS);
+ RUNTIME_CHECK(isc__timer_register() == ISC_R_SUCCESS);
+}
+
+void
+isc_lib_register() {
+ RUNTIME_CHECK(isc_once_do(&register_once, do_register)
+ == ISC_R_SUCCESS);
+}
+#endif
diff --git a/contrib/ntp/libntp/lib/isc/log.c b/contrib/ntp/libntp/lib/isc/log.c
new file mode 100644
index 000000000000..dfe4fdfd497a
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/log.c
@@ -0,0 +1,1767 @@
+/*
+ * Copyright (C) 2004-2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file
+ * \author Principal Authors: DCL */
+
+#include <config.h>
+
+#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <time.h>
+
+#include <sys/types.h> /* dev_t FreeBSD 2.1 */
+
+#include <isc/dir.h>
+#include <isc/file.h>
+#include <isc/log.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/print.h>
+#include <isc/stat.h>
+#include <isc/stdio.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+#include "ntp_stdlib.h" /* NTP change for strlcpy, strlcat */
+
+#define LCTX_MAGIC ISC_MAGIC('L', 'c', 't', 'x')
+#define VALID_CONTEXT(lctx) ISC_MAGIC_VALID(lctx, LCTX_MAGIC)
+
+#define LCFG_MAGIC ISC_MAGIC('L', 'c', 'f', 'g')
+#define VALID_CONFIG(lcfg) ISC_MAGIC_VALID(lcfg, LCFG_MAGIC)
+
+/*
+ * XXXDCL make dynamic?
+ */
+#define LOG_BUFFER_SIZE (8 * 1024)
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* AIX and others don't define this. */
+#endif
+
+/*!
+ * This is the structure that holds each named channel. A simple linked
+ * list chains all of the channels together, so an individual channel is
+ * found by doing strcmp()s with the names down the list. Their should
+ * be no performance penalty from this as it is expected that the number
+ * of named channels will be no more than a dozen or so, and name lookups
+ * from the head of the list are only done when isc_log_usechannel() is
+ * called, which should also be very infrequent.
+ */
+typedef struct isc_logchannel isc_logchannel_t;
+
+struct isc_logchannel {
+ char * name;
+ unsigned int type;
+ int level;
+ unsigned int flags;
+ isc_logdestination_t destination;
+ ISC_LINK(isc_logchannel_t) link;
+};
+
+/*!
+ * The logchannellist structure associates categories and modules with
+ * channels. First the appropriate channellist is found based on the
+ * category, and then each structure in the linked list is checked for
+ * a matching module. It is expected that the number of channels
+ * associated with any given category will be very short, no more than
+ * three or four in the more unusual cases.
+ */
+typedef struct isc_logchannellist isc_logchannellist_t;
+
+struct isc_logchannellist {
+ const isc_logmodule_t * module;
+ isc_logchannel_t * channel;
+ ISC_LINK(isc_logchannellist_t) link;
+};
+
+/*!
+ * This structure is used to remember messages for pruning via
+ * isc_log_[v]write1().
+ */
+typedef struct isc_logmessage isc_logmessage_t;
+
+struct isc_logmessage {
+ char * text;
+ isc_time_t time;
+ ISC_LINK(isc_logmessage_t) link;
+};
+
+/*!
+ * The isc_logconfig structure is used to store the configurable information
+ * about where messages are actually supposed to be sent -- the information
+ * that could changed based on some configuration file, as opposed to the
+ * the category/module specification of isc_log_[v]write[1] that is compiled
+ * into a program, or the debug_level which is dynamic state information.
+ */
+struct isc_logconfig {
+ unsigned int magic;
+ isc_log_t * lctx;
+ ISC_LIST(isc_logchannel_t) channels;
+ ISC_LIST(isc_logchannellist_t) *channellists;
+ unsigned int channellist_count;
+ unsigned int duplicate_interval;
+ int highest_level;
+ char * tag;
+ isc_boolean_t dynamic;
+};
+
+/*!
+ * This isc_log structure provides the context for the isc_log functions.
+ * The log context locks itself in isc_log_doit, the internal backend to
+ * isc_log_write. The locking is necessary both to provide exclusive access
+ * to the buffer into which the message is formatted and to guard against
+ * competing threads trying to write to the same syslog resource. (On
+ * some systems, such as BSD/OS, stdio is thread safe but syslog is not.)
+ * Unfortunately, the lock cannot guard against a _different_ logging
+ * context in the same program competing for syslog's attention. Thus
+ * There Can Be Only One, but this is not enforced.
+ * XXXDCL enforce it?
+ *
+ * Note that the category and module information is not locked.
+ * This is because in the usual case, only one isc_log_t is ever created
+ * in a program, and the category/module registration happens only once.
+ * XXXDCL it might be wise to add more locking overall.
+ */
+struct isc_log {
+ /* Not locked. */
+ unsigned int magic;
+ isc_mem_t * mctx;
+ isc_logcategory_t * categories;
+ unsigned int category_count;
+ isc_logmodule_t * modules;
+ unsigned int module_count;
+ int debug_level;
+ isc_mutex_t lock;
+ /* Locked by isc_log lock. */
+ isc_logconfig_t * logconfig;
+ char buffer[LOG_BUFFER_SIZE];
+ ISC_LIST(isc_logmessage_t) messages;
+};
+
+/*!
+ * Used when ISC_LOG_PRINTLEVEL is enabled for a channel.
+ */
+static const char *log_level_strings[] = {
+ "debug",
+ "info",
+ "notice",
+ "warning",
+ "error",
+ "critical"
+};
+
+/*!
+ * Used to convert ISC_LOG_* priorities into syslog priorities.
+ * XXXDCL This will need modification for NT.
+ */
+static const int syslog_map[] = {
+ LOG_DEBUG,
+ LOG_INFO,
+ LOG_NOTICE,
+ LOG_WARNING,
+ LOG_ERR,
+ LOG_CRIT
+};
+
+/*!
+ * When adding new categories, a corresponding ISC_LOGCATEGORY_foo
+ * definition needs to be added to <isc/log.h>.
+ *
+ * The default category is provided so that the internal default can
+ * be overridden. Since the default is always looked up as the first
+ * channellist in the log context, it must come first in isc_categories[].
+ */
+LIBISC_EXTERNAL_DATA isc_logcategory_t isc_categories[] = {
+ { "default", 0 }, /* "default" must come first. */
+ { "general", 0 },
+ { NULL, 0 }
+};
+
+/*!
+ * See above comment for categories on LIBISC_EXTERNAL_DATA, and apply it to modules.
+ */
+LIBISC_EXTERNAL_DATA isc_logmodule_t isc_modules[] = {
+ { "socket", 0 },
+ { "time", 0 },
+ { "interface", 0 },
+ { "timer", 0 },
+ { "file", 0 },
+ { NULL, 0 }
+};
+
+/*!
+ * This essentially constant structure must be filled in at run time,
+ * because its channel member is pointed to a channel that is created
+ * dynamically with isc_log_createchannel.
+ */
+static isc_logchannellist_t default_channel;
+
+/*!
+ * libisc logs to this context.
+ */
+LIBISC_EXTERNAL_DATA isc_log_t *isc_lctx = NULL;
+
+/*!
+ * Forward declarations.
+ */
+static isc_result_t
+assignchannel(isc_logconfig_t *lcfg, unsigned int category_id,
+ const isc_logmodule_t *module, isc_logchannel_t *channel);
+
+static isc_result_t
+sync_channellist(isc_logconfig_t *lcfg);
+
+static isc_result_t
+greatest_version(isc_logchannel_t *channel, int *greatest);
+
+static isc_result_t
+roll_log(isc_logchannel_t *channel);
+
+static void
+isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, isc_boolean_t write_once,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, va_list args)
+ ISC_FORMAT_PRINTF(9, 0);
+
+/*@{*/
+/*!
+ * Convenience macros.
+ */
+
+#define FACILITY(channel) (channel->destination.facility)
+#define FILE_NAME(channel) (channel->destination.file.name)
+#define FILE_STREAM(channel) (channel->destination.file.stream)
+#define FILE_VERSIONS(channel) (channel->destination.file.versions)
+#define FILE_MAXSIZE(channel) (channel->destination.file.maximum_size)
+#define FILE_MAXREACHED(channel) (channel->destination.file.maximum_reached)
+
+/*@}*/
+/****
+ **** Public interfaces.
+ ****/
+
+/*
+ * Establish a new logging context, with default channels.
+ */
+isc_result_t
+isc_log_create(isc_mem_t *mctx, isc_log_t **lctxp, isc_logconfig_t **lcfgp) {
+ isc_log_t *lctx;
+ isc_logconfig_t *lcfg = NULL;
+ isc_result_t result;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(lctxp != NULL && *lctxp == NULL);
+ REQUIRE(lcfgp == NULL || *lcfgp == NULL);
+
+ lctx = isc_mem_get(mctx, sizeof(*lctx));
+ if (lctx != NULL) {
+ lctx->mctx = mctx;
+ lctx->categories = NULL;
+ lctx->category_count = 0;
+ lctx->modules = NULL;
+ lctx->module_count = 0;
+ lctx->debug_level = 0;
+
+ ISC_LIST_INIT(lctx->messages);
+
+ result = isc_mutex_init(&lctx->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(mctx, lctx, sizeof(*lctx));
+ return (result);
+ }
+
+ /*
+ * Normally setting the magic number is the last step done
+ * in a creation function, but a valid log context is needed
+ * by isc_log_registercategories and isc_logconfig_create.
+ * If either fails, the lctx is destroyed and not returned
+ * to the caller.
+ */
+ lctx->magic = LCTX_MAGIC;
+
+ isc_log_registercategories(lctx, isc_categories);
+ isc_log_registermodules(lctx, isc_modules);
+ result = isc_logconfig_create(lctx, &lcfg);
+
+ } else
+ result = ISC_R_NOMEMORY;
+
+ if (result == ISC_R_SUCCESS)
+ result = sync_channellist(lcfg);
+
+ if (result == ISC_R_SUCCESS) {
+ lctx->logconfig = lcfg;
+
+ *lctxp = lctx;
+ if (lcfgp != NULL)
+ *lcfgp = lcfg;
+
+ } else {
+ if (lcfg != NULL)
+ isc_logconfig_destroy(&lcfg);
+ if (lctx != NULL)
+ isc_log_destroy(&lctx);
+ }
+
+ return (result);
+}
+
+isc_result_t
+isc_logconfig_create(isc_log_t *lctx, isc_logconfig_t **lcfgp) {
+ isc_logconfig_t *lcfg;
+ isc_logdestination_t destination;
+ isc_result_t result = ISC_R_SUCCESS;
+ int level = ISC_LOG_INFO;
+
+ REQUIRE(lcfgp != NULL && *lcfgp == NULL);
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ lcfg = isc_mem_get(lctx->mctx, sizeof(*lcfg));
+
+ if (lcfg != NULL) {
+ lcfg->lctx = lctx;
+ lcfg->channellists = NULL;
+ lcfg->channellist_count = 0;
+ lcfg->duplicate_interval = 0;
+ lcfg->highest_level = level;
+ lcfg->tag = NULL;
+ lcfg->dynamic = ISC_FALSE;
+
+ ISC_LIST_INIT(lcfg->channels);
+
+ /*
+ * Normally the magic number is the last thing set in the
+ * structure, but isc_log_createchannel() needs a valid
+ * config. If the channel creation fails, the lcfg is not
+ * returned to the caller.
+ */
+ lcfg->magic = LCFG_MAGIC;
+
+ } else
+ result = ISC_R_NOMEMORY;
+
+ /*
+ * Create the default channels:
+ * default_syslog, default_stderr, default_debug and null.
+ */
+ if (result == ISC_R_SUCCESS) {
+ destination.facility = LOG_DAEMON;
+ result = isc_log_createchannel(lcfg, "default_syslog",
+ ISC_LOG_TOSYSLOG, level,
+ &destination, 0);
+ }
+
+ if (result == ISC_R_SUCCESS) {
+ destination.file.stream = stderr;
+ destination.file.name = NULL;
+ destination.file.versions = ISC_LOG_ROLLNEVER;
+ destination.file.maximum_size = 0;
+ result = isc_log_createchannel(lcfg, "default_stderr",
+ ISC_LOG_TOFILEDESC,
+ level,
+ &destination,
+ ISC_LOG_PRINTTIME);
+ }
+
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Set the default category's channel to default_stderr,
+ * which is at the head of the channels list because it was
+ * just created.
+ */
+ default_channel.channel = ISC_LIST_HEAD(lcfg->channels);
+
+ destination.file.stream = stderr;
+ destination.file.name = NULL;
+ destination.file.versions = ISC_LOG_ROLLNEVER;
+ destination.file.maximum_size = 0;
+ result = isc_log_createchannel(lcfg, "default_debug",
+ ISC_LOG_TOFILEDESC,
+ ISC_LOG_DYNAMIC,
+ &destination,
+ ISC_LOG_PRINTTIME);
+ }
+
+ if (result == ISC_R_SUCCESS)
+ result = isc_log_createchannel(lcfg, "null",
+ ISC_LOG_TONULL,
+ ISC_LOG_DYNAMIC,
+ NULL, 0);
+
+ if (result == ISC_R_SUCCESS)
+ *lcfgp = lcfg;
+
+ else
+ if (lcfg != NULL)
+ isc_logconfig_destroy(&lcfg);
+
+ return (result);
+}
+
+isc_logconfig_t *
+isc_logconfig_get(isc_log_t *lctx) {
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ ENSURE(lctx->logconfig != NULL);
+
+ return (lctx->logconfig);
+}
+
+isc_result_t
+isc_logconfig_use(isc_log_t *lctx, isc_logconfig_t *lcfg) {
+ isc_logconfig_t *old_cfg;
+ isc_result_t result;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(VALID_CONFIG(lcfg));
+ REQUIRE(lcfg->lctx == lctx);
+
+ /*
+ * Ensure that lcfg->channellist_count == lctx->category_count.
+ * They won't be equal if isc_log_usechannel has not been called
+ * since any call to isc_log_registercategories.
+ */
+ result = sync_channellist(lcfg);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ LOCK(&lctx->lock);
+
+ old_cfg = lctx->logconfig;
+ lctx->logconfig = lcfg;
+
+ UNLOCK(&lctx->lock);
+
+ isc_logconfig_destroy(&old_cfg);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_log_destroy(isc_log_t **lctxp) {
+ isc_log_t *lctx;
+ isc_logconfig_t *lcfg;
+ isc_mem_t *mctx;
+ isc_logmessage_t *message;
+
+ REQUIRE(lctxp != NULL && VALID_CONTEXT(*lctxp));
+
+ lctx = *lctxp;
+ mctx = lctx->mctx;
+
+ if (lctx->logconfig != NULL) {
+ lcfg = lctx->logconfig;
+ lctx->logconfig = NULL;
+ isc_logconfig_destroy(&lcfg);
+ }
+
+ DESTROYLOCK(&lctx->lock);
+
+ while ((message = ISC_LIST_HEAD(lctx->messages)) != NULL) {
+ ISC_LIST_UNLINK(lctx->messages, message, link);
+
+ isc_mem_put(mctx, message,
+ sizeof(*message) + strlen(message->text) + 1);
+ }
+
+ lctx->buffer[0] = '\0';
+ lctx->debug_level = 0;
+ lctx->categories = NULL;
+ lctx->category_count = 0;
+ lctx->modules = NULL;
+ lctx->module_count = 0;
+ lctx->mctx = NULL;
+ lctx->magic = 0;
+
+ isc_mem_put(mctx, lctx, sizeof(*lctx));
+
+ *lctxp = NULL;
+}
+
+void
+isc_logconfig_destroy(isc_logconfig_t **lcfgp) {
+ isc_logconfig_t *lcfg;
+ isc_mem_t *mctx;
+ isc_logchannel_t *channel;
+ isc_logchannellist_t *item;
+ char *filename;
+ unsigned int i;
+
+ REQUIRE(lcfgp != NULL && VALID_CONFIG(*lcfgp));
+
+ lcfg = *lcfgp;
+
+ /*
+ * This function cannot be called with a logconfig that is in
+ * use by a log context.
+ */
+ REQUIRE(lcfg->lctx != NULL && lcfg->lctx->logconfig != lcfg);
+
+ mctx = lcfg->lctx->mctx;
+
+ while ((channel = ISC_LIST_HEAD(lcfg->channels)) != NULL) {
+ ISC_LIST_UNLINK(lcfg->channels, channel, link);
+
+ if (channel->type == ISC_LOG_TOFILE) {
+ /*
+ * The filename for the channel may have ultimately
+ * started its life in user-land as a const string,
+ * but in isc_log_createchannel it gets copied
+ * into writable memory and is not longer truly const.
+ */
+ DE_CONST(FILE_NAME(channel), filename);
+ isc_mem_free(mctx, filename);
+
+ if (FILE_STREAM(channel) != NULL)
+ (void)fclose(FILE_STREAM(channel));
+ }
+
+ isc_mem_free(mctx, channel->name);
+ isc_mem_put(mctx, channel, sizeof(*channel));
+ }
+
+ for (i = 0; i < lcfg->channellist_count; i++)
+ while ((item = ISC_LIST_HEAD(lcfg->channellists[i])) != NULL) {
+ ISC_LIST_UNLINK(lcfg->channellists[i], item, link);
+ isc_mem_put(mctx, item, sizeof(*item));
+ }
+
+ if (lcfg->channellist_count > 0)
+ isc_mem_put(mctx, lcfg->channellists,
+ lcfg->channellist_count *
+ sizeof(ISC_LIST(isc_logchannellist_t)));
+
+ lcfg->dynamic = ISC_FALSE;
+ if (lcfg->tag != NULL)
+ isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
+ lcfg->tag = NULL;
+ lcfg->highest_level = 0;
+ lcfg->duplicate_interval = 0;
+ lcfg->magic = 0;
+
+ isc_mem_put(mctx, lcfg, sizeof(*lcfg));
+
+ *lcfgp = NULL;
+}
+
+void
+isc_log_registercategories(isc_log_t *lctx, isc_logcategory_t categories[]) {
+ isc_logcategory_t *catp;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(categories != NULL && categories[0].name != NULL);
+
+ /*
+ * XXXDCL This somewhat sleazy situation of using the last pointer
+ * in one category array to point to the next array exists because
+ * this registration function returns void and I didn't want to have
+ * change everything that used it by making it return an isc_result_t.
+ * It would need to do that if it had to allocate memory to store
+ * pointers to each array passed in.
+ */
+ if (lctx->categories == NULL)
+ lctx->categories = categories;
+
+ else {
+ /*
+ * Adjust the last (NULL) pointer of the already registered
+ * categories to point to the incoming array.
+ */
+ for (catp = lctx->categories; catp->name != NULL; )
+ if (catp->id == UINT_MAX)
+ /*
+ * The name pointer points to the next array.
+ * Ick.
+ */
+ DE_CONST(catp->name, catp);
+ else
+ catp++;
+
+ catp->name = (void *)categories;
+ catp->id = UINT_MAX;
+ }
+
+ /*
+ * Update the id number of the category with its new global id.
+ */
+ for (catp = categories; catp->name != NULL; catp++)
+ catp->id = lctx->category_count++;
+}
+
+isc_logcategory_t *
+isc_log_categorybyname(isc_log_t *lctx, const char *name) {
+ isc_logcategory_t *catp;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(name != NULL);
+
+ for (catp = lctx->categories; catp->name != NULL; )
+ if (catp->id == UINT_MAX)
+ /*
+ * catp is neither modified nor returned to the
+ * caller, so removing its const qualifier is ok.
+ */
+ DE_CONST(catp->name, catp);
+ else {
+ if (strcmp(catp->name, name) == 0)
+ return (catp);
+ catp++;
+ }
+
+ return (NULL);
+}
+
+void
+isc_log_registermodules(isc_log_t *lctx, isc_logmodule_t modules[]) {
+ isc_logmodule_t *modp;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(modules != NULL && modules[0].name != NULL);
+
+ /*
+ * XXXDCL This somewhat sleazy situation of using the last pointer
+ * in one category array to point to the next array exists because
+ * this registration function returns void and I didn't want to have
+ * change everything that used it by making it return an isc_result_t.
+ * It would need to do that if it had to allocate memory to store
+ * pointers to each array passed in.
+ */
+ if (lctx->modules == NULL)
+ lctx->modules = modules;
+
+ else {
+ /*
+ * Adjust the last (NULL) pointer of the already registered
+ * modules to point to the incoming array.
+ */
+ for (modp = lctx->modules; modp->name != NULL; )
+ if (modp->id == UINT_MAX)
+ /*
+ * The name pointer points to the next array.
+ * Ick.
+ */
+ DE_CONST(modp->name, modp);
+ else
+ modp++;
+
+ modp->name = (void *)modules;
+ modp->id = UINT_MAX;
+ }
+
+ /*
+ * Update the id number of the module with its new global id.
+ */
+ for (modp = modules; modp->name != NULL; modp++)
+ modp->id = lctx->module_count++;
+}
+
+isc_logmodule_t *
+isc_log_modulebyname(isc_log_t *lctx, const char *name) {
+ isc_logmodule_t *modp;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+ REQUIRE(name != NULL);
+
+ for (modp = lctx->modules; modp->name != NULL; )
+ if (modp->id == UINT_MAX)
+ /*
+ * modp is neither modified nor returned to the
+ * caller, so removing its const qualifier is ok.
+ */
+ DE_CONST(modp->name, modp);
+ else {
+ if (strcmp(modp->name, name) == 0)
+ return (modp);
+ modp++;
+ }
+
+ return (NULL);
+}
+
+isc_result_t
+isc_log_createchannel(isc_logconfig_t *lcfg, const char *name,
+ unsigned int type, int level,
+ const isc_logdestination_t *destination,
+ unsigned int flags)
+{
+ isc_logchannel_t *channel;
+ isc_mem_t *mctx;
+
+ REQUIRE(VALID_CONFIG(lcfg));
+ REQUIRE(name != NULL);
+ REQUIRE(type == ISC_LOG_TOSYSLOG || type == ISC_LOG_TOFILE ||
+ type == ISC_LOG_TOFILEDESC || type == ISC_LOG_TONULL);
+ REQUIRE(destination != NULL || type == ISC_LOG_TONULL);
+ REQUIRE(level >= ISC_LOG_CRITICAL);
+ REQUIRE((flags &
+ (unsigned int)~(ISC_LOG_PRINTALL | ISC_LOG_DEBUGONLY)) == 0);
+
+ /* XXXDCL find duplicate names? */
+
+ mctx = lcfg->lctx->mctx;
+
+ channel = isc_mem_get(mctx, sizeof(*channel));
+ if (channel == NULL)
+ return (ISC_R_NOMEMORY);
+
+ channel->name = isc_mem_strdup(mctx, name);
+ if (channel->name == NULL) {
+ isc_mem_put(mctx, channel, sizeof(*channel));
+ return (ISC_R_NOMEMORY);
+ }
+
+ channel->type = type;
+ channel->level = level;
+ channel->flags = flags;
+ ISC_LINK_INIT(channel, link);
+
+ switch (type) {
+ case ISC_LOG_TOSYSLOG:
+ FACILITY(channel) = destination->facility;
+ break;
+
+ case ISC_LOG_TOFILE:
+ /*
+ * The file name is copied because greatest_version wants
+ * to scribble on it, so it needs to be definitely in
+ * writable memory.
+ */
+ FILE_NAME(channel) =
+ isc_mem_strdup(mctx, destination->file.name);
+ FILE_STREAM(channel) = NULL;
+ FILE_VERSIONS(channel) = destination->file.versions;
+ FILE_MAXSIZE(channel) = destination->file.maximum_size;
+ FILE_MAXREACHED(channel) = ISC_FALSE;
+ break;
+
+ case ISC_LOG_TOFILEDESC:
+ FILE_NAME(channel) = NULL;
+ FILE_STREAM(channel) = destination->file.stream;
+ FILE_MAXSIZE(channel) = 0;
+ FILE_VERSIONS(channel) = ISC_LOG_ROLLNEVER;
+ break;
+
+ case ISC_LOG_TONULL:
+ /* Nothing. */
+ break;
+
+ default:
+ isc_mem_put(mctx, channel->name, strlen(channel->name) + 1);
+ isc_mem_put(mctx, channel, sizeof(*channel));
+ return (ISC_R_UNEXPECTED);
+ }
+
+ ISC_LIST_PREPEND(lcfg->channels, channel, link);
+
+ /*
+ * If default_stderr was redefined, make the default category
+ * point to the new default_stderr.
+ */
+ if (strcmp(name, "default_stderr") == 0)
+ default_channel.channel = channel;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_log_usechannel(isc_logconfig_t *lcfg, const char *name,
+ const isc_logcategory_t *category,
+ const isc_logmodule_t *module)
+{
+ isc_log_t *lctx;
+ isc_logchannel_t *channel;
+ isc_result_t result = ISC_R_SUCCESS;
+ unsigned int i;
+
+ REQUIRE(VALID_CONFIG(lcfg));
+ REQUIRE(name != NULL);
+
+ lctx = lcfg->lctx;
+
+ REQUIRE(category == NULL || category->id < lctx->category_count);
+ REQUIRE(module == NULL || module->id < lctx->module_count);
+
+ for (channel = ISC_LIST_HEAD(lcfg->channels); channel != NULL;
+ channel = ISC_LIST_NEXT(channel, link))
+ if (strcmp(name, channel->name) == 0)
+ break;
+
+ if (channel == NULL)
+ return (ISC_R_NOTFOUND);
+
+ if (category != NULL)
+ result = assignchannel(lcfg, category->id, module, channel);
+
+ else
+ /*
+ * Assign to all categories. Note that this includes
+ * the default channel.
+ */
+ for (i = 0; i < lctx->category_count; i++) {
+ result = assignchannel(lcfg, i, module, channel);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
+
+ return (result);
+}
+
+void
+isc_log_write(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *format, ...)
+{
+ va_list args;
+
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+
+ va_start(args, format);
+ isc_log_doit(lctx, category, module, level, ISC_FALSE,
+ NULL, 0, 0, format, args);
+ va_end(args);
+}
+
+void
+isc_log_vwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, va_list args)
+{
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+ isc_log_doit(lctx, category, module, level, ISC_FALSE,
+ NULL, 0, 0, format, args);
+}
+
+void
+isc_log_write1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, const char *format, ...)
+{
+ va_list args;
+
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+
+ va_start(args, format);
+ isc_log_doit(lctx, category, module, level, ISC_TRUE,
+ NULL, 0, 0, format, args);
+ va_end(args);
+}
+
+void
+isc_log_vwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ const char *format, va_list args)
+{
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+ isc_log_doit(lctx, category, module, level, ISC_TRUE,
+ NULL, 0, 0, format, args);
+}
+
+void
+isc_log_iwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, ...)
+{
+ va_list args;
+
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+
+ va_start(args, format);
+ isc_log_doit(lctx, category, module, level, ISC_FALSE,
+ msgcat, msgset, msg, format, args);
+ va_end(args);
+}
+
+void
+isc_log_ivwrite(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, va_list args)
+{
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+ isc_log_doit(lctx, category, module, level, ISC_FALSE,
+ msgcat, msgset, msg, format, args);
+}
+
+void
+isc_log_iwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, ...)
+{
+ va_list args;
+
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+
+ va_start(args, format);
+ isc_log_doit(lctx, category, module, level, ISC_TRUE,
+ msgcat, msgset, msg, format, args);
+ va_end(args);
+}
+
+void
+isc_log_ivwrite1(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, va_list args)
+{
+ /*
+ * Contract checking is done in isc_log_doit().
+ */
+ isc_log_doit(lctx, category, module, level, ISC_TRUE,
+ msgcat, msgset, msg, format, args);
+}
+
+void
+isc_log_setcontext(isc_log_t *lctx) {
+ isc_lctx = lctx;
+}
+
+void
+isc_log_setdebuglevel(isc_log_t *lctx, unsigned int level) {
+ isc_logchannel_t *channel;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ LOCK(&lctx->lock);
+
+ lctx->debug_level = level;
+ /*
+ * Close ISC_LOG_DEBUGONLY channels if level is zero.
+ */
+ if (lctx->debug_level == 0)
+ for (channel = ISC_LIST_HEAD(lctx->logconfig->channels);
+ channel != NULL;
+ channel = ISC_LIST_NEXT(channel, link))
+ if (channel->type == ISC_LOG_TOFILE &&
+ (channel->flags & ISC_LOG_DEBUGONLY) != 0 &&
+ FILE_STREAM(channel) != NULL) {
+ (void)fclose(FILE_STREAM(channel));
+ FILE_STREAM(channel) = NULL;
+ }
+ UNLOCK(&lctx->lock);
+}
+
+unsigned int
+isc_log_getdebuglevel(isc_log_t *lctx) {
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ return (lctx->debug_level);
+}
+
+void
+isc_log_setduplicateinterval(isc_logconfig_t *lcfg, unsigned int interval) {
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ lcfg->duplicate_interval = interval;
+}
+
+unsigned int
+isc_log_getduplicateinterval(isc_logconfig_t *lcfg) {
+ REQUIRE(VALID_CONTEXT(lcfg));
+
+ return (lcfg->duplicate_interval);
+}
+
+isc_result_t
+isc_log_settag(isc_logconfig_t *lcfg, const char *tag) {
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ if (tag != NULL && *tag != '\0') {
+ if (lcfg->tag != NULL)
+ isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
+ lcfg->tag = isc_mem_strdup(lcfg->lctx->mctx, tag);
+ if (lcfg->tag == NULL)
+ return (ISC_R_NOMEMORY);
+
+ } else {
+ if (lcfg->tag != NULL)
+ isc_mem_free(lcfg->lctx->mctx, lcfg->tag);
+ lcfg->tag = NULL;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+char *
+isc_log_gettag(isc_logconfig_t *lcfg) {
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ return (lcfg->tag);
+}
+
+/* XXXDCL NT -- This interface will assuredly be changing. */
+void
+isc_log_opensyslog(const char *tag, int options, int facility) {
+ (void)openlog(tag, options, facility);
+}
+
+void
+isc_log_closefilelogs(isc_log_t *lctx) {
+ isc_logchannel_t *channel;
+
+ REQUIRE(VALID_CONTEXT(lctx));
+
+ LOCK(&lctx->lock);
+ for (channel = ISC_LIST_HEAD(lctx->logconfig->channels);
+ channel != NULL;
+ channel = ISC_LIST_NEXT(channel, link))
+
+ if (channel->type == ISC_LOG_TOFILE &&
+ FILE_STREAM(channel) != NULL) {
+ (void)fclose(FILE_STREAM(channel));
+ FILE_STREAM(channel) = NULL;
+ }
+ UNLOCK(&lctx->lock);
+}
+
+/****
+ **** Internal functions
+ ****/
+
+static isc_result_t
+assignchannel(isc_logconfig_t *lcfg, unsigned int category_id,
+ const isc_logmodule_t *module, isc_logchannel_t *channel)
+{
+ isc_logchannellist_t *new_item;
+ isc_log_t *lctx;
+ isc_result_t result;
+
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ lctx = lcfg->lctx;
+
+ REQUIRE(category_id < lctx->category_count);
+ REQUIRE(module == NULL || module->id < lctx->module_count);
+ REQUIRE(channel != NULL);
+
+ /*
+ * Ensure lcfg->channellist_count == lctx->category_count.
+ */
+ result = sync_channellist(lcfg);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ new_item = isc_mem_get(lctx->mctx, sizeof(*new_item));
+ if (new_item == NULL)
+ return (ISC_R_NOMEMORY);
+
+ new_item->channel = channel;
+ new_item->module = module;
+ ISC_LIST_INITANDPREPEND(lcfg->channellists[category_id],
+ new_item, link);
+
+ /*
+ * Remember the highest logging level set by any channel in the
+ * logging config, so isc_log_doit() can quickly return if the
+ * message is too high to be logged by any channel.
+ */
+ if (channel->type != ISC_LOG_TONULL) {
+ if (lcfg->highest_level < channel->level)
+ lcfg->highest_level = channel->level;
+ if (channel->level == ISC_LOG_DYNAMIC)
+ lcfg->dynamic = ISC_TRUE;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * This would ideally be part of isc_log_registercategories(), except then
+ * that function would have to return isc_result_t instead of void.
+ */
+static isc_result_t
+sync_channellist(isc_logconfig_t *lcfg) {
+ unsigned int bytes;
+ isc_log_t *lctx;
+ void *lists;
+
+ REQUIRE(VALID_CONFIG(lcfg));
+
+ lctx = lcfg->lctx;
+
+ REQUIRE(lctx->category_count != 0);
+
+ if (lctx->category_count == lcfg->channellist_count)
+ return (ISC_R_SUCCESS);
+
+ bytes = lctx->category_count * sizeof(ISC_LIST(isc_logchannellist_t));
+
+ lists = isc_mem_get(lctx->mctx, bytes);
+
+ if (lists == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(lists, 0, bytes);
+
+ if (lcfg->channellist_count != 0) {
+ bytes = lcfg->channellist_count *
+ sizeof(ISC_LIST(isc_logchannellist_t));
+ memcpy(lists, lcfg->channellists, bytes);
+ isc_mem_put(lctx->mctx, lcfg->channellists, bytes);
+ }
+
+ lcfg->channellists = lists;
+ lcfg->channellist_count = lctx->category_count;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+greatest_version(isc_logchannel_t *channel, int *greatestp) {
+ /* XXXDCL HIGHLY NT */
+ char *basenam, *digit_end;
+ const char *dirname;
+ int version, greatest = -1;
+ size_t basenamelen;
+ isc_dir_t dir;
+ isc_result_t result;
+ char sep = '/';
+#ifdef _WIN32
+ char *basename2;
+#endif
+
+ REQUIRE(channel->type == ISC_LOG_TOFILE);
+
+ /*
+ * It is safe to DE_CONST the file.name because it was copied
+ * with isc_mem_strdup in isc_log_createchannel.
+ */
+ basenam = strrchr(FILE_NAME(channel), sep);
+#ifdef _WIN32
+ basename2 = strrchr(FILE_NAME(channel), '\\');
+ if ((basenam != NULL && basename2 != NULL && basename2 > basenam) ||
+ (basenam == NULL && basename2 != NULL)) {
+ basenam = basename2;
+ sep = '\\';
+ }
+#endif
+ if (basenam != NULL) {
+ *basenam++ = '\0';
+ dirname = FILE_NAME(channel);
+ } else {
+ DE_CONST(FILE_NAME(channel), basenam);
+ dirname = ".";
+ }
+ basenamelen = strlen(basenam);
+
+ isc_dir_init(&dir);
+ result = isc_dir_open(&dir, dirname);
+
+ /*
+ * Replace the file separator if it was taken out.
+ */
+ if (basenam != FILE_NAME(channel))
+ *(basenam - 1) = sep;
+
+ /*
+ * Return if the directory open failed.
+ */
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ while (isc_dir_read(&dir) == ISC_R_SUCCESS) {
+ if (dir.entry.length > basenamelen &&
+ strncmp(dir.entry.name, basenam, basenamelen) == 0 &&
+ dir.entry.name[basenamelen] == '.') {
+
+ version = strtol(&dir.entry.name[basenamelen + 1],
+ &digit_end, 10);
+ if (*digit_end == '\0' && version > greatest)
+ greatest = version;
+ }
+ }
+ isc_dir_close(&dir);
+
+ *greatestp = ++greatest;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+roll_log(isc_logchannel_t *channel) {
+ int i, n, greatest;
+ char current[PATH_MAX + 1];
+ char new[PATH_MAX + 1];
+ const char *path;
+ isc_result_t result;
+
+ /*
+ * Do nothing (not even excess version trimming) if ISC_LOG_ROLLNEVER
+ * is specified. Apparently complete external control over the log
+ * files is desired.
+ */
+ if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)
+ return (ISC_R_SUCCESS);
+
+ path = FILE_NAME(channel);
+
+ /*
+ * Set greatest_version to the greatest existing version
+ * (not the maximum requested version). This is 1 based even
+ * though the file names are 0 based, so an oldest log of log.1
+ * is a greatest_version of 2.
+ */
+ result = greatest_version(channel, &greatest);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*
+ * Now greatest should be set to the highest version number desired.
+ * Since the highest number is one less than FILE_VERSIONS(channel)
+ * when not doing infinite log rolling, greatest will need to be
+ * decremented when it is equal to -- or greater than --
+ * FILE_VERSIONS(channel). When greatest is less than
+ * FILE_VERSIONS(channel), it is already suitable for use as
+ * the maximum version number.
+ */
+
+ if (FILE_VERSIONS(channel) == ISC_LOG_ROLLINFINITE ||
+ FILE_VERSIONS(channel) > greatest)
+ ; /* Do nothing. */
+ else
+ /*
+ * When greatest is >= FILE_VERSIONS(channel), it needs to
+ * be reduced until it is FILE_VERSIONS(channel) - 1.
+ * Remove any excess logs on the way to that value.
+ */
+ while (--greatest >= FILE_VERSIONS(channel)) {
+ n = snprintf(current, sizeof(current), "%s.%d",
+ path, greatest);
+ if (n >= (int)sizeof(current) || n < 0)
+ result = ISC_R_NOSPACE;
+ else
+ result = isc_file_remove(current);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_FILENOTFOUND)
+ syslog(LOG_ERR,
+ "unable to remove log file '%s.%d': %s",
+ path, greatest,
+ isc_result_totext(result));
+ }
+
+ for (i = greatest; i > 0; i--) {
+ result = ISC_R_SUCCESS;
+ n = snprintf(current, sizeof(current), "%s.%d", path, i - 1);
+ if (n >= (int)sizeof(current) || n < 0)
+ result = ISC_R_NOSPACE;
+ if (result == ISC_R_SUCCESS) {
+ n = snprintf(new, sizeof(new), "%s.%d", path, i);
+ if (n >= (int)sizeof(new) || n < 0)
+ result = ISC_R_NOSPACE;
+ }
+ if (result == ISC_R_SUCCESS)
+ result = isc_file_rename(current, new);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_FILENOTFOUND)
+ syslog(LOG_ERR,
+ "unable to rename log file '%s.%d' to "
+ "'%s.%d': %s", path, i - 1, path, i,
+ isc_result_totext(result));
+ }
+
+ if (FILE_VERSIONS(channel) != 0) {
+ n = snprintf(new, sizeof(new), "%s.0", path);
+ if (n >= (int)sizeof(new) || n < 0)
+ result = ISC_R_NOSPACE;
+ else
+ result = isc_file_rename(path, new);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_FILENOTFOUND)
+ syslog(LOG_ERR,
+ "unable to rename log file '%s' to '%s.0': %s",
+ path, path, isc_result_totext(result));
+ } else {
+ result = isc_file_remove(path);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_FILENOTFOUND)
+ syslog(LOG_ERR, "unable to remove log file '%s': %s",
+ path, isc_result_totext(result));
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+isc_log_open(isc_logchannel_t *channel) {
+ struct stat statbuf;
+ isc_boolean_t regular_file;
+ isc_boolean_t roll = ISC_FALSE;
+ isc_result_t result = ISC_R_SUCCESS;
+ const char *path;
+
+ REQUIRE(channel->type == ISC_LOG_TOFILE);
+ REQUIRE(FILE_STREAM(channel) == NULL);
+
+ path = FILE_NAME(channel);
+
+ REQUIRE(path != NULL && *path != '\0');
+
+ /*
+ * Determine type of file; only regular files will be
+ * version renamed, and only if the base file exists
+ * and either has no size limit or has reached its size limit.
+ */
+ if (stat(path, &statbuf) == 0) {
+ regular_file = S_ISREG(statbuf.st_mode) ? ISC_TRUE : ISC_FALSE;
+ /* XXXDCL if not regular_file complain? */
+ if ((FILE_MAXSIZE(channel) == 0 &&
+ FILE_VERSIONS(channel) != ISC_LOG_ROLLNEVER) ||
+ (FILE_MAXSIZE(channel) > 0 &&
+ statbuf.st_size >= FILE_MAXSIZE(channel)))
+ roll = regular_file;
+ } else if (errno == ENOENT) {
+ regular_file = ISC_TRUE;
+ POST(regular_file);
+ } else
+ result = ISC_R_INVALIDFILE;
+
+ /*
+ * Version control.
+ */
+ if (result == ISC_R_SUCCESS && roll) {
+ if (FILE_VERSIONS(channel) == ISC_LOG_ROLLNEVER)
+ return (ISC_R_MAXSIZE);
+ result = roll_log(channel);
+ if (result != ISC_R_SUCCESS) {
+ if ((channel->flags & ISC_LOG_OPENERR) == 0) {
+ syslog(LOG_ERR,
+ "isc_log_open: roll_log '%s' "
+ "failed: %s",
+ FILE_NAME(channel),
+ isc_result_totext(result));
+ channel->flags |= ISC_LOG_OPENERR;
+ }
+ return (result);
+ }
+ }
+
+ result = isc_stdio_open(path, "a", &FILE_STREAM(channel));
+
+ return (result);
+}
+
+isc_boolean_t
+isc_log_wouldlog(isc_log_t *lctx, int level) {
+ /*
+ * Try to avoid locking the mutex for messages which can't
+ * possibly be logged to any channels -- primarily debugging
+ * messages that the debug level is not high enough to print.
+ *
+ * If the level is (mathematically) less than or equal to the
+ * highest_level, or if there is a dynamic channel and the level is
+ * less than or equal to the debug level, the main loop must be
+ * entered to see if the message should really be output.
+ *
+ * NOTE: this is UNLOCKED access to the logconfig. However,
+ * the worst thing that can happen is that a bad decision is made
+ * about returning without logging, and that's not a big concern,
+ * because that's a risk anyway if the logconfig is being
+ * dynamically changed.
+ */
+
+ if (lctx == NULL || lctx->logconfig == NULL)
+ return (ISC_FALSE);
+
+ return (ISC_TF(level <= lctx->logconfig->highest_level ||
+ (lctx->logconfig->dynamic &&
+ level <= lctx->debug_level)));
+}
+
+static void
+isc_log_doit(isc_log_t *lctx, isc_logcategory_t *category,
+ isc_logmodule_t *module, int level, isc_boolean_t write_once,
+ isc_msgcat_t *msgcat, int msgset, int msg,
+ const char *format, va_list args)
+{
+ int syslog_level;
+ char time_string[64];
+ char level_string[24];
+ size_t octets;
+ const char *iformat;
+ struct stat statbuf;
+ isc_boolean_t matched = ISC_FALSE;
+ isc_boolean_t printtime, printtag;
+ isc_boolean_t printcategory, printmodule, printlevel;
+ isc_logconfig_t *lcfg;
+ isc_logchannel_t *channel;
+ isc_logchannellist_t *category_channels;
+ isc_result_t result;
+
+ REQUIRE(lctx == NULL || VALID_CONTEXT(lctx));
+ REQUIRE(category != NULL);
+ REQUIRE(module != NULL);
+ REQUIRE(level != ISC_LOG_DYNAMIC);
+ REQUIRE(format != NULL);
+
+ /*
+ * Programs can use libraries that use this logging code without
+ * wanting to do any logging, thus the log context is allowed to
+ * be non-existent.
+ */
+ if (lctx == NULL)
+ return;
+
+ REQUIRE(category->id < lctx->category_count);
+ REQUIRE(module->id < lctx->module_count);
+
+ if (! isc_log_wouldlog(lctx, level))
+ return;
+
+ if (msgcat != NULL)
+ iformat = isc_msgcat_get(msgcat, msgset, msg, format);
+ else
+ iformat = format;
+
+ time_string[0] = '\0';
+ level_string[0] = '\0';
+
+ LOCK(&lctx->lock);
+
+ lctx->buffer[0] = '\0';
+
+ lcfg = lctx->logconfig;
+
+ category_channels = ISC_LIST_HEAD(lcfg->channellists[category->id]);
+
+ /*
+ * XXXDCL add duplicate filtering? (To not write multiple times to
+ * the same source via various channels).
+ */
+ do {
+ /*
+ * If the channel list end was reached and a match was made,
+ * everything is finished.
+ */
+ if (category_channels == NULL && matched)
+ break;
+
+ if (category_channels == NULL && ! matched &&
+ category_channels != ISC_LIST_HEAD(lcfg->channellists[0]))
+ /*
+ * No category/module pair was explicitly configured.
+ * Try the category named "default".
+ */
+ category_channels =
+ ISC_LIST_HEAD(lcfg->channellists[0]);
+
+ if (category_channels == NULL && ! matched)
+ /*
+ * No matching module was explicitly configured
+ * for the category named "default". Use the internal
+ * default channel.
+ */
+ category_channels = &default_channel;
+
+ if (category_channels->module != NULL &&
+ category_channels->module != module) {
+ category_channels = ISC_LIST_NEXT(category_channels,
+ link);
+ continue;
+ }
+
+ matched = ISC_TRUE;
+
+ channel = category_channels->channel;
+ category_channels = ISC_LIST_NEXT(category_channels, link);
+
+ if (((channel->flags & ISC_LOG_DEBUGONLY) != 0) &&
+ lctx->debug_level == 0)
+ continue;
+
+ if (channel->level == ISC_LOG_DYNAMIC) {
+ if (lctx->debug_level < level)
+ continue;
+ } else if (channel->level < level)
+ continue;
+
+ if ((channel->flags & ISC_LOG_PRINTTIME) != 0 &&
+ time_string[0] == '\0') {
+ isc_time_t isctime;
+
+ TIME_NOW(&isctime);
+ isc_time_formattimestamp(&isctime, time_string,
+ sizeof(time_string));
+ }
+
+ if ((channel->flags & ISC_LOG_PRINTLEVEL) != 0 &&
+ level_string[0] == '\0') {
+ if (level < ISC_LOG_CRITICAL)
+ snprintf(level_string, sizeof(level_string),
+ "%s %d: ",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_LOG,
+ ISC_MSG_LEVEL,
+ "level"),
+ level);
+ else if (level > ISC_LOG_DYNAMIC)
+ snprintf(level_string, sizeof(level_string),
+ "%s %d: ", log_level_strings[0],
+ level);
+ else
+ snprintf(level_string, sizeof(level_string),
+ "%s: ", log_level_strings[-level]);
+ }
+
+ /*
+ * Only format the message once.
+ */
+ if (lctx->buffer[0] == '\0') {
+ (void)vsnprintf(lctx->buffer, sizeof(lctx->buffer),
+ iformat, args);
+
+ /*
+ * Check for duplicates.
+ */
+ if (write_once) {
+ isc_logmessage_t *message, *new;
+ isc_time_t oldest;
+ isc_interval_t interval;
+
+ isc_interval_set(&interval,
+ lcfg->duplicate_interval, 0);
+
+ /*
+ * 'oldest' is the age of the oldest messages
+ * which fall within the duplicate_interval
+ * range.
+ */
+ TIME_NOW(&oldest);
+ if (isc_time_subtract(&oldest, &interval, &oldest)
+ != ISC_R_SUCCESS)
+ /*
+ * Can't effectively do the checking
+ * without having a valid time.
+ */
+ message = NULL;
+ else
+ message =ISC_LIST_HEAD(lctx->messages);
+
+ while (message != NULL) {
+ if (isc_time_compare(&message->time,
+ &oldest) < 0) {
+ /*
+ * This message is older
+ * than the duplicate_interval,
+ * so it should be dropped from
+ * the history.
+ *
+ * Setting the interval to be
+ * to be longer will obviously
+ * not cause the expired
+ * message to spring back into
+ * existence.
+ */
+ new = ISC_LIST_NEXT(message,
+ link);
+
+ ISC_LIST_UNLINK(lctx->messages,
+ message, link);
+
+ isc_mem_put(lctx->mctx,
+ message,
+ sizeof(*message) + 1 +
+ strlen(message->text));
+
+ message = new;
+ continue;
+ }
+
+ /*
+ * This message is in the duplicate
+ * filtering interval ...
+ */
+ if (strcmp(lctx->buffer, message->text)
+ == 0) {
+ /*
+ * ... and it is a duplicate.
+ * Unlock the mutex and
+ * get the hell out of Dodge.
+ */
+ UNLOCK(&lctx->lock);
+ return;
+ }
+
+ message = ISC_LIST_NEXT(message, link);
+ }
+
+ /*
+ * It wasn't in the duplicate interval,
+ * so add it to the message list.
+ */
+ octets = strlen(lctx->buffer) + 1;
+ new = isc_mem_get(lctx->mctx,
+ sizeof(isc_logmessage_t) +
+ octets);
+ if (new != NULL) {
+ /*
+ * Put the text immediately after
+ * the struct. The strcpy is safe.
+ */
+ new->text = (char *)(new + 1);
+ strlcpy(new->text, lctx->buffer, octets);
+
+ TIME_NOW(&new->time);
+
+ ISC_LIST_APPEND(lctx->messages,
+ new, link);
+ }
+ }
+ }
+
+ printtime = ISC_TF((channel->flags & ISC_LOG_PRINTTIME)
+ != 0);
+ printtag = ISC_TF((channel->flags & ISC_LOG_PRINTTAG)
+ != 0 && lcfg->tag != NULL);
+ printcategory = ISC_TF((channel->flags & ISC_LOG_PRINTCATEGORY)
+ != 0);
+ printmodule = ISC_TF((channel->flags & ISC_LOG_PRINTMODULE)
+ != 0);
+ printlevel = ISC_TF((channel->flags & ISC_LOG_PRINTLEVEL)
+ != 0);
+
+ switch (channel->type) {
+ case ISC_LOG_TOFILE:
+ if (FILE_MAXREACHED(channel)) {
+ /*
+ * If the file can be rolled, OR
+ * If the file no longer exists, OR
+ * If the file is less than the maximum size,
+ * (such as if it had been renamed and
+ * a new one touched, or it was truncated
+ * in place)
+ * ... then close it to trigger reopening.
+ */
+ if (FILE_VERSIONS(channel) !=
+ ISC_LOG_ROLLNEVER ||
+ (stat(FILE_NAME(channel), &statbuf) != 0 &&
+ errno == ENOENT) ||
+ statbuf.st_size < FILE_MAXSIZE(channel)) {
+ (void)fclose(FILE_STREAM(channel));
+ FILE_STREAM(channel) = NULL;
+ FILE_MAXREACHED(channel) = ISC_FALSE;
+ } else
+ /*
+ * Eh, skip it.
+ */
+ break;
+ }
+
+ if (FILE_STREAM(channel) == NULL) {
+ result = isc_log_open(channel);
+ if (result != ISC_R_SUCCESS &&
+ result != ISC_R_MAXSIZE &&
+ (channel->flags & ISC_LOG_OPENERR) == 0) {
+ syslog(LOG_ERR,
+ "isc_log_open '%s' failed: %s",
+ FILE_NAME(channel),
+ isc_result_totext(result));
+ channel->flags |= ISC_LOG_OPENERR;
+ }
+ if (result != ISC_R_SUCCESS)
+ break;
+ channel->flags &= ~ISC_LOG_OPENERR;
+ }
+ /* FALLTHROUGH */
+
+ case ISC_LOG_TOFILEDESC:
+ fprintf(FILE_STREAM(channel), "%s%s%s%s%s%s%s%s%s%s\n",
+ printtime ? time_string : "",
+ printtime ? " " : "",
+ printtag ? lcfg->tag : "",
+ printtag ? ": " : "",
+ printcategory ? category->name : "",
+ printcategory ? ": " : "",
+ printmodule ? (module != NULL ? module->name
+ : "no_module")
+ : "",
+ printmodule ? ": " : "",
+ printlevel ? level_string : "",
+ lctx->buffer);
+
+ fflush(FILE_STREAM(channel));
+
+ /*
+ * If the file now exceeds its maximum size
+ * threshold, note it so that it will not be logged
+ * to any more.
+ */
+ if (FILE_MAXSIZE(channel) > 0) {
+ INSIST(channel->type == ISC_LOG_TOFILE);
+
+ /* XXXDCL NT fstat/fileno */
+ /* XXXDCL complain if fstat fails? */
+ if (fstat(fileno(FILE_STREAM(channel)),
+ &statbuf) >= 0 &&
+ statbuf.st_size > FILE_MAXSIZE(channel))
+ FILE_MAXREACHED(channel) = ISC_TRUE;
+ }
+
+ break;
+
+ case ISC_LOG_TOSYSLOG:
+ if (level > 0)
+ syslog_level = LOG_DEBUG;
+ else if (level < ISC_LOG_CRITICAL)
+ syslog_level = LOG_CRIT;
+ else
+ syslog_level = syslog_map[-level];
+
+ (void)syslog(FACILITY(channel) | syslog_level,
+ "%s%s%s%s%s%s%s%s%s%s",
+ printtime ? time_string : "",
+ printtime ? " " : "",
+ printtag ? lcfg->tag : "",
+ printtag ? ": " : "",
+ printcategory ? category->name : "",
+ printcategory ? ": " : "",
+ printmodule ? (module != NULL ? module->name
+ : "no_module")
+ : "",
+ printmodule ? ": " : "",
+ printlevel ? level_string : "",
+ lctx->buffer);
+ break;
+
+ case ISC_LOG_TONULL:
+ break;
+
+ }
+
+ } while (1);
+
+ UNLOCK(&lctx->lock);
+}
diff --git a/contrib/ntp/libntp/lib/isc/md5.c b/contrib/ntp/libntp/lib/isc/md5.c
new file mode 100644
index 000000000000..7c6419b2a9c7
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/md5.c
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: md5.c,v 1.16 2009/02/06 23:47:42 tbox Exp $ */
+
+/*! \file
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ */
+
+#include "config.h"
+
+#include <isc/assertions.h>
+#include <isc/md5.h>
+#include <isc/platform.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_md5_init(isc_md5_t *ctx) {
+ EVP_DigestInit(ctx, EVP_md5());
+}
+
+void
+isc_md5_invalidate(isc_md5_t *ctx) {
+ EVP_MD_CTX_cleanup(ctx);
+}
+
+void
+isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
+ EVP_DigestUpdate(ctx, (const void *) buf, (size_t) len);
+}
+
+void
+isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
+ EVP_DigestFinal(ctx, digest, NULL);
+}
+
+#else
+
+static void
+byteSwap(isc_uint32_t *buf, unsigned words)
+{
+ unsigned char *p = (unsigned char *)buf;
+
+ do {
+ *buf++ = (isc_uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 |
+ ((unsigned)p[1] << 8 | p[0]);
+ p += 4;
+ } while (--words);
+}
+
+/*!
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+isc_md5_init(isc_md5_t *ctx) {
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bytes[0] = 0;
+ ctx->bytes[1] = 0;
+}
+
+void
+isc_md5_invalidate(isc_md5_t *ctx) {
+ memset(ctx, 0, sizeof(isc_md5_t));
+}
+
+/*@{*/
+/*! The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+/*@}*/
+
+/*! This is the central step in the MD5 algorithm. */
+#define MD5STEP(f,w,x,y,z,in,s) \
+ (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
+
+/*!
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+static void
+transform(isc_uint32_t buf[4], isc_uint32_t const in[16]) {
+ register isc_uint32_t a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+/*!
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_md5_update(isc_md5_t *ctx, const unsigned char *buf, unsigned int len) {
+ isc_uint32_t t;
+
+ /* Update byte count */
+
+ t = ctx->bytes[0];
+ if ((ctx->bytes[0] = t + len) < t)
+ ctx->bytes[1]++; /* Carry from low to high */
+
+ t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
+ if (t > len) {
+ memcpy((unsigned char *)ctx->in + 64 - t, buf, len);
+ return;
+ }
+ /* First chunk is an odd size */
+ memcpy((unsigned char *)ctx->in + 64 - t, buf, t);
+ byteSwap(ctx->in, 16);
+ transform(ctx->buf, ctx->in);
+ buf += t;
+ len -= t;
+
+ /* Process data in 64-byte chunks */
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteSwap(ctx->in, 16);
+ transform(ctx->buf, ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+ memcpy(ctx->in, buf, len);
+}
+
+/*!
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+isc_md5_final(isc_md5_t *ctx, unsigned char *digest) {
+ int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
+ unsigned char *p = (unsigned char *)ctx->in + count;
+
+ /* Set the first char of padding to 0x80. There is always room. */
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 56 bytes (-8..55) */
+ count = 56 - 1 - count;
+
+ if (count < 0) { /* Padding forces an extra block */
+ memset(p, 0, count + 8);
+ byteSwap(ctx->in, 16);
+ transform(ctx->buf, ctx->in);
+ p = (unsigned char *)ctx->in;
+ count = 56;
+ }
+ memset(p, 0, count);
+ byteSwap(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ctx->in[14] = ctx->bytes[0] << 3;
+ ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
+ transform(ctx->buf, ctx->in);
+
+ byteSwap(ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset(ctx, 0, sizeof(isc_md5_t)); /* In case it's sensitive */
+}
+#endif
diff --git a/contrib/ntp/libntp/lib/isc/netaddr.c b/contrib/ntp/libntp/lib/isc/netaddr.c
new file mode 100644
index 000000000000..01f908043495
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/netaddr.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2010-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <isc/buffer.h>
+#include <isc/msgs.h>
+#include <isc/net.h>
+#include <isc/netaddr.h>
+#include <isc/print.h>
+#include <isc/sockaddr.h>
+#include <isc/string.h>
+#include <isc/util.h>
+#include "ntp_stdlib.h" /* NTP change for strlcpy, strlcat */
+
+isc_boolean_t
+isc_netaddr_equal(const isc_netaddr_t *a, const isc_netaddr_t *b) {
+ REQUIRE(a != NULL && b != NULL);
+
+ if (a->family != b->family)
+ return (ISC_FALSE);
+
+ if (a->zone != b->zone)
+ return (ISC_FALSE);
+
+ switch (a->family) {
+ case AF_INET:
+ if (a->type.in.s_addr != b->type.in.s_addr)
+ return (ISC_FALSE);
+ break;
+ case AF_INET6:
+ if (memcmp(&a->type.in6, &b->type.in6,
+ sizeof(a->type.in6)) != 0 ||
+ a->zone != b->zone)
+ return (ISC_FALSE);
+ break;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ case AF_UNIX:
+ if (strcmp(a->type.un, b->type.un) != 0)
+ return (ISC_FALSE);
+ break;
+#endif
+ default:
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+isc_boolean_t
+isc_netaddr_eqprefix(const isc_netaddr_t *a, const isc_netaddr_t *b,
+ unsigned int prefixlen)
+{
+ const unsigned char *pa = NULL, *pb = NULL;
+ unsigned int ipabytes = 0; /* Length of whole IP address in bytes */
+ unsigned int nbytes; /* Number of significant whole bytes */
+ unsigned int nbits; /* Number of significant leftover bits */
+
+ REQUIRE(a != NULL && b != NULL);
+
+ if (a->family != b->family)
+ return (ISC_FALSE);
+
+ if (a->zone != b->zone && b->zone != 0)
+ return (ISC_FALSE);
+
+ switch (a->family) {
+ case AF_INET:
+ pa = (const unsigned char *) &a->type.in;
+ pb = (const unsigned char *) &b->type.in;
+ ipabytes = 4;
+ break;
+ case AF_INET6:
+ pa = (const unsigned char *) &a->type.in6;
+ pb = (const unsigned char *) &b->type.in6;
+ ipabytes = 16;
+ break;
+ default:
+ return (ISC_FALSE);
+ }
+
+ /*
+ * Don't crash if we get a pattern like 10.0.0.1/9999999.
+ */
+ if (prefixlen > ipabytes * 8)
+ prefixlen = ipabytes * 8;
+
+ nbytes = prefixlen / 8;
+ nbits = prefixlen % 8;
+
+ if (nbytes > 0) {
+ if (memcmp(pa, pb, nbytes) != 0)
+ return (ISC_FALSE);
+ }
+ if (nbits > 0) {
+ unsigned int bytea, byteb, mask;
+ INSIST(nbytes < ipabytes);
+ INSIST(nbits < 8);
+ bytea = pa[nbytes];
+ byteb = pb[nbytes];
+ mask = (0xFF << (8-nbits)) & 0xFF;
+ if ((bytea & mask) != (byteb & mask))
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+isc_result_t
+isc_netaddr_totext(const isc_netaddr_t *netaddr, isc_buffer_t *target) {
+ char abuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
+ char zbuf[sizeof("%4294967295")];
+ unsigned int alen;
+ int zlen;
+ const char *r;
+ const void *type;
+
+ REQUIRE(netaddr != NULL);
+
+ switch (netaddr->family) {
+ case AF_INET:
+ type = &netaddr->type.in;
+ break;
+ case AF_INET6:
+ type = &netaddr->type.in6;
+ break;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ case AF_UNIX:
+ alen = strlen(netaddr->type.un);
+ if (alen > isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+ isc_buffer_putmem(target,
+ (const unsigned char *)(netaddr->type.un),
+ alen);
+ return (ISC_R_SUCCESS);
+#endif
+ default:
+ return (ISC_R_FAILURE);
+ }
+ r = inet_ntop(netaddr->family, type, abuf, sizeof(abuf));
+ if (r == NULL)
+ return (ISC_R_FAILURE);
+
+ alen = (unsigned int)strlen(abuf); /* no overflow possible */
+ INSIST(alen < sizeof(abuf));
+
+ zlen = 0;
+ if (netaddr->family == AF_INET6 && netaddr->zone != 0) {
+ zlen = snprintf(zbuf, sizeof(zbuf), "%%%u", netaddr->zone);
+ if (zlen < 0)
+ return (ISC_R_FAILURE);
+ INSIST((unsigned int)zlen < sizeof(zbuf));
+ }
+
+ if (alen + zlen > isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+
+ isc_buffer_putmem(target, (unsigned char *)abuf, alen);
+ isc_buffer_putmem(target, (unsigned char *)zbuf, zlen);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_netaddr_format(const isc_netaddr_t *na, char *array, unsigned int size) {
+ isc_result_t result;
+ isc_buffer_t buf;
+
+ isc_buffer_init(&buf, array, size);
+ result = isc_netaddr_totext(na, &buf);
+
+ if (size == 0)
+ return;
+
+ /*
+ * Null terminate.
+ */
+ if (result == ISC_R_SUCCESS) {
+ if (isc_buffer_availablelength(&buf) >= 1)
+ isc_buffer_putuint8(&buf, 0);
+ else
+ result = ISC_R_NOSPACE;
+ }
+
+ if (result != ISC_R_SUCCESS) {
+ snprintf(array, size,
+ "<%s %u>",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_NETADDR,
+ ISC_MSG_UNKNOWNADDR,
+ "unknown address, family"),
+ na->family);
+ array[size - 1] = '\0';
+ }
+}
+
+
+isc_result_t
+isc_netaddr_prefixok(const isc_netaddr_t *na, unsigned int prefixlen) {
+ static const unsigned char zeros[16] = { 0 };
+ unsigned int nbits, nbytes, ipbytes = 0;
+ const unsigned char *p;
+
+ switch (na->family) {
+ case AF_INET:
+ p = (const unsigned char *) &na->type.in;
+ ipbytes = 4;
+ if (prefixlen > 32)
+ return (ISC_R_RANGE);
+ break;
+ case AF_INET6:
+ p = (const unsigned char *) &na->type.in6;
+ ipbytes = 16;
+ if (prefixlen > 128)
+ return (ISC_R_RANGE);
+ break;
+ default:
+ return (ISC_R_NOTIMPLEMENTED);
+ }
+ nbytes = prefixlen / 8;
+ nbits = prefixlen % 8;
+ if (nbits != 0) {
+ if ((p[nbytes] & (0xff>>nbits)) != 0U)
+ return (ISC_R_FAILURE);
+ nbytes++;
+ }
+ if (memcmp(p + nbytes, zeros, ipbytes - nbytes) != 0)
+ return (ISC_R_FAILURE);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_netaddr_masktoprefixlen(const isc_netaddr_t *s, unsigned int *lenp) {
+ unsigned int nbits = 0, nbytes = 0, ipbytes = 0, i;
+ const unsigned char *p;
+
+ switch (s->family) {
+ case AF_INET:
+ p = (const unsigned char *) &s->type.in;
+ ipbytes = 4;
+ break;
+ case AF_INET6:
+ p = (const unsigned char *) &s->type.in6;
+ ipbytes = 16;
+ break;
+ default:
+ return (ISC_R_NOTIMPLEMENTED);
+ }
+ for (i = 0; i < ipbytes; i++) {
+ if (p[i] != 0xFF)
+ break;
+ }
+ nbytes = i;
+ if (i < ipbytes) {
+ unsigned int c = p[nbytes];
+ while ((c & 0x80) != 0 && nbits < 8) {
+ c <<= 1; nbits++;
+ }
+ if ((c & 0xFF) != 0)
+ return (ISC_R_MASKNONCONTIG);
+ i++;
+ }
+ for (; i < ipbytes; i++) {
+ if (p[i] != 0)
+ return (ISC_R_MASKNONCONTIG);
+ }
+ *lenp = nbytes * 8 + nbits;
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_netaddr_fromin(isc_netaddr_t *netaddr, const struct in_addr *ina) {
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_INET;
+ netaddr->type.in = *ina;
+}
+
+void
+isc_netaddr_fromin6(isc_netaddr_t *netaddr, const struct in6_addr *ina6) {
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_INET6;
+ netaddr->type.in6 = *ina6;
+}
+
+isc_result_t
+isc_netaddr_frompath(isc_netaddr_t *netaddr, const char *path) {
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ if (strlen(path) > sizeof(netaddr->type.un) - 1)
+ return (ISC_R_NOSPACE);
+
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_UNIX;
+ strlcpy(netaddr->type.un, path, sizeof(netaddr->type.un));
+ netaddr->zone = 0;
+ return (ISC_R_SUCCESS);
+#else
+ UNUSED(netaddr);
+ UNUSED(path);
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
+
+
+void
+isc_netaddr_setzone(isc_netaddr_t *netaddr, isc_uint32_t zone) {
+ /* we currently only support AF_INET6. */
+ REQUIRE(netaddr->family == AF_INET6);
+
+ netaddr->zone = zone;
+}
+
+isc_uint32_t
+isc_netaddr_getzone(const isc_netaddr_t *netaddr) {
+ return (netaddr->zone);
+}
+
+void
+isc_netaddr_fromsockaddr(isc_netaddr_t *t, const isc_sockaddr_t *s) {
+ int family = s->type.sa.sa_family;
+ t->family = family;
+ switch (family) {
+ case AF_INET:
+ t->type.in = s->type.sin.sin_addr;
+ t->zone = 0;
+ break;
+ case AF_INET6:
+ memcpy(&t->type.in6, &s->type.sin6.sin6_addr, 16);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ t->zone = s->type.sin6.sin6_scope_id;
+#else
+ t->zone = 0;
+#endif
+ break;
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ case AF_UNIX:
+ memcpy(t->type.un, s->type.sunix.sun_path, sizeof(t->type.un));
+ t->zone = 0;
+ break;
+#endif
+ default:
+ INSIST(0);
+ }
+}
+
+void
+isc_netaddr_any(isc_netaddr_t *netaddr) {
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_INET;
+ netaddr->type.in.s_addr = INADDR_ANY;
+}
+
+void
+isc_netaddr_any6(isc_netaddr_t *netaddr) {
+ memset(netaddr, 0, sizeof(*netaddr));
+ netaddr->family = AF_INET6;
+ netaddr->type.in6 = in6addr_any;
+}
+
+isc_boolean_t
+isc_netaddr_ismulticast(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_TF(ISC_IPADDR_ISMULTICAST(na->type.in.s_addr)));
+ case AF_INET6:
+ return (ISC_TF(IN6_IS_ADDR_MULTICAST(&na->type.in6)));
+ default:
+ return (ISC_FALSE); /* XXXMLG ? */
+ }
+}
+
+isc_boolean_t
+isc_netaddr_isexperimental(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_TF(ISC_IPADDR_ISEXPERIMENTAL(na->type.in.s_addr)));
+ default:
+ return (ISC_FALSE); /* XXXMLG ? */
+ }
+}
+
+isc_boolean_t
+isc_netaddr_islinklocal(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_FALSE);
+ case AF_INET6:
+ return (ISC_TF(IN6_IS_ADDR_LINKLOCAL(&na->type.in6)));
+ default:
+ return (ISC_FALSE);
+ }
+}
+
+isc_boolean_t
+isc_netaddr_issitelocal(isc_netaddr_t *na) {
+ switch (na->family) {
+ case AF_INET:
+ return (ISC_FALSE);
+ case AF_INET6:
+ return (ISC_TF(IN6_IS_ADDR_SITELOCAL(&na->type.in6)));
+ default:
+ return (ISC_FALSE);
+ }
+}
+
+void
+isc_netaddr_fromv4mapped(isc_netaddr_t *t, const isc_netaddr_t *s) {
+ isc_netaddr_t *src;
+
+ DE_CONST(s, src); /* Must come before IN6_IS_ADDR_V4MAPPED. */
+
+ REQUIRE(s->family == AF_INET6);
+ REQUIRE(IN6_IS_ADDR_V4MAPPED(&src->type.in6));
+
+ memset(t, 0, sizeof(*t));
+ t->family = AF_INET;
+ memcpy(&t->type.in, (char *)&src->type.in6 + 12, 4);
+ return;
+}
diff --git a/contrib/ntp/libntp/lib/isc/netscope.c b/contrib/ntp/libntp/lib/isc/netscope.c
new file mode 100644
index 000000000000..9aa11db9a8ce
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/netscope.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2004-2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*! \file */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] =
+ "$Id: netscope.c,v 1.13 2007/06/19 23:47:17 tbox Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <isc/string.h>
+#include <isc/net.h>
+#include <isc/netscope.h>
+#include <isc/result.h>
+
+isc_result_t
+isc_netscope_pton(int af, char *scopename, void *addr, isc_uint32_t *zoneid) {
+ char *ep;
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ unsigned int ifid;
+#endif
+ struct in6_addr *in6;
+ isc_uint32_t zone;
+ isc_uint64_t llz;
+
+ /* at this moment, we only support AF_INET6 */
+ if (af != AF_INET6)
+ return (ISC_R_FAILURE);
+
+ in6 = (struct in6_addr *)addr;
+
+ /*
+ * Basically, "names" are more stable than numeric IDs in terms of
+ * renumbering, and are more preferred. However, since there is no
+ * standard naming convention and APIs to deal with the names. Thus,
+ * we only handle the case of link-local addresses, for which we use
+ * interface names as link names, assuming one to one mapping between
+ * interfaces and links.
+ */
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ if (IN6_IS_ADDR_LINKLOCAL(in6) &&
+ (ifid = if_nametoindex((const char *)scopename)) != 0)
+ zone = (isc_uint32_t)ifid;
+ else {
+#endif
+ llz = isc_string_touint64(scopename, &ep, 10);
+ if (ep == scopename)
+ return (ISC_R_FAILURE);
+
+ /* check overflow */
+ zone = (isc_uint32_t)(llz & 0xffffffffUL);
+ if (zone != llz)
+ return (ISC_R_FAILURE);
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ }
+#endif
+
+ *zoneid = zone;
+ return (ISC_R_SUCCESS);
+}
diff --git a/contrib/ntp/libntp/lib/isc/nls/msgcat.c b/contrib/ntp/libntp/lib/isc/nls/msgcat.c
new file mode 100644
index 000000000000..3d6b6764d582
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/nls/msgcat.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: msgcat.c,v 1.18 2007/06/19 23:47:18 tbox Exp $ */
+
+/*! \file msgcat.c
+ *
+ * \author Principal Author: Bob Halley
+ */
+
+#include <config.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include <isc/magic.h>
+#include <isc/msgcat.h>
+#include <isc/util.h>
+
+#ifdef HAVE_CATGETS
+#include <nl_types.h> /* Required for nl_catd. */
+#endif
+
+/*
+ * Implementation Notes:
+ *
+ * We use malloc() and free() instead of isc_mem_get() and isc_mem_put()
+ * because we don't want to require a memory context to be specified
+ * in order to use a message catalog.
+ */
+
+struct isc_msgcat {
+ unsigned int magic;
+#ifdef HAVE_CATGETS
+ nl_catd catalog;
+#endif
+};
+
+#define MSGCAT_MAGIC ISC_MAGIC('M', 'C', 'a', 't')
+#define VALID_MSGCAT(m) ISC_MAGIC_VALID(m, MSGCAT_MAGIC)
+
+void
+isc_msgcat_open(const char *name, isc_msgcat_t **msgcatp) {
+ isc_msgcat_t *msgcat;
+
+ /*
+ * Open a message catalog.
+ */
+
+ REQUIRE(name != NULL);
+ REQUIRE(msgcatp != NULL && *msgcatp == NULL);
+
+ msgcat = malloc(sizeof(*msgcat));
+ if (msgcat == NULL) {
+ *msgcatp = NULL;
+ return;
+ }
+
+#ifdef HAVE_CATGETS
+ /*
+ * We don't check if catopen() fails because we don't care.
+ * If it does fail, then when we call catgets(), it will use
+ * the default string.
+ */
+ msgcat->catalog = catopen(name, 0);
+#endif
+ msgcat->magic = MSGCAT_MAGIC;
+
+ *msgcatp = msgcat;
+}
+
+void
+isc_msgcat_close(isc_msgcat_t **msgcatp) {
+ isc_msgcat_t *msgcat;
+
+ /*
+ * Close a message catalog.
+ */
+
+ REQUIRE(msgcatp != NULL);
+ msgcat = *msgcatp;
+ REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL);
+
+ if (msgcat != NULL) {
+#ifdef HAVE_CATGETS
+ if (msgcat->catalog != (nl_catd)(-1))
+ (void)catclose(msgcat->catalog);
+#endif
+ msgcat->magic = 0;
+ free(msgcat);
+ }
+
+ *msgcatp = NULL;
+}
+
+const char *
+isc_msgcat_get(isc_msgcat_t *msgcat, int set, int message,
+ const char *default_text)
+{
+ /*
+ * Get message 'message' from message set 'set' in 'msgcat'. If it
+ * is not available, use 'default'.
+ */
+
+ REQUIRE(VALID_MSGCAT(msgcat) || msgcat == NULL);
+ REQUIRE(set > 0);
+ REQUIRE(message > 0);
+ REQUIRE(default_text != NULL);
+
+#ifdef HAVE_CATGETS
+ if (msgcat == NULL)
+ return (default_text);
+ return (catgets(msgcat->catalog, set, message, default_text));
+#else
+ return (default_text);
+#endif
+}
diff --git a/contrib/ntp/libntp/lib/isc/nothreads/condition.c b/contrib/ntp/libntp/lib/isc/nothreads/condition.c
new file mode 100644
index 000000000000..9be8f835f46f
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/nothreads/condition.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: condition.c,v 1.10 2007/06/19 23:47:18 tbox Exp $ */
+
+#include <config.h>
+
+#include <isc/util.h>
+
+EMPTY_TRANSLATION_UNIT
diff --git a/contrib/ntp/libntp/lib/isc/nothreads/include/isc/condition.h b/contrib/ntp/libntp/lib/isc/nothreads/include/isc/condition.h
new file mode 100644
index 000000000000..b269f82fc0ba
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/nothreads/include/isc/condition.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: condition.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */
+
+/*
+ * This provides a limited subset of the isc_condition_t
+ * functionality for use by single-threaded programs that
+ * need to block waiting for events. Only a single
+ * call to isc_condition_wait() may be blocked at any given
+ * time, and the _waituntil and _broadcast functions are not
+ * supported. This is intended primarily for use by the omapi
+ * library, and may go away once omapi goes away. Use for
+ * other purposes is strongly discouraged.
+ */
+
+#ifndef ISC_CONDITION_H
+#define ISC_CONDITION_H 1
+
+#include <isc/mutex.h>
+
+typedef int isc_condition_t;
+
+isc_result_t isc__nothread_wait_hack(isc_condition_t *cp, isc_mutex_t *mp);
+isc_result_t isc__nothread_signal_hack(isc_condition_t *cp);
+
+#define isc_condition_init(cp) \
+ (*(cp) = 0, ISC_R_SUCCESS)
+
+#define isc_condition_wait(cp, mp) \
+ isc__nothread_wait_hack(cp, mp)
+
+#define isc_condition_waituntil(cp, mp, tp) \
+ ((void)(cp), (void)(mp), (void)(tp), ISC_R_NOTIMPLEMENTED)
+
+#define isc_condition_signal(cp) \
+ isc__nothread_signal_hack(cp)
+
+#define isc_condition_broadcast(cp) \
+ ((void)(cp), ISC_R_NOTIMPLEMENTED)
+
+#define isc_condition_destroy(cp) \
+ (*(cp) == 0 ? (*(cp) = -1, ISC_R_SUCCESS) : ISC_R_UNEXPECTED)
+
+#endif /* ISC_CONDITION_H */
diff --git a/contrib/ntp/libntp/lib/isc/nothreads/include/isc/mutex.h b/contrib/ntp/libntp/lib/isc/nothreads/include/isc/mutex.h
new file mode 100644
index 000000000000..1f2187b8b53f
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/nothreads/include/isc/mutex.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mutex.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_MUTEX_H
+#define ISC_MUTEX_H 1
+
+#include <isc/result.h> /* for ISC_R_ codes */
+
+typedef int isc_mutex_t;
+
+#define isc_mutex_init(mp) \
+ (*(mp) = 0, ISC_R_SUCCESS)
+#define isc_mutex_lock(mp) \
+ ((*(mp))++ == 0 ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#define isc_mutex_unlock(mp) \
+ (--(*(mp)) == 0 ? ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#define isc_mutex_trylock(mp) \
+ (*(mp) == 0 ? ((*(mp))++, ISC_R_SUCCESS) : ISC_R_LOCKBUSY)
+#define isc_mutex_destroy(mp) \
+ (*(mp) == 0 ? (*(mp) = -1, ISC_R_SUCCESS) : ISC_R_UNEXPECTED)
+#define isc_mutex_stats(fp)
+
+#endif /* ISC_MUTEX_H */
diff --git a/contrib/ntp/libntp/lib/isc/nothreads/include/isc/once.h b/contrib/ntp/libntp/lib/isc/nothreads/include/isc/once.h
new file mode 100644
index 000000000000..ab705a4a4792
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/nothreads/include/isc/once.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: once.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_ONCE_H
+#define ISC_ONCE_H 1
+
+#include <isc/result.h>
+
+typedef isc_boolean_t isc_once_t;
+
+#define ISC_ONCE_INIT ISC_FALSE
+
+#define isc_once_do(op, f) \
+ (!*(op) ? (f(), *(op) = ISC_TRUE, ISC_R_SUCCESS) : ISC_R_SUCCESS)
+
+#endif /* ISC_ONCE_H */
diff --git a/contrib/ntp/libntp/lib/isc/nothreads/include/isc/thread.h b/contrib/ntp/libntp/lib/isc/nothreads/include/isc/thread.h
new file mode 100644
index 000000000000..313bc5f9590a
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/nothreads/include/isc/thread.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: thread.h,v 1.6 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_THREAD_H
+#define ISC_THREAD_H 1
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_thread_setconcurrency(unsigned int level);
+
+#define isc_thread_self() ((unsigned long)0)
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_THREAD_H */
diff --git a/contrib/ntp/libntp/lib/isc/nothreads/thread.c b/contrib/ntp/libntp/lib/isc/nothreads/thread.c
new file mode 100644
index 000000000000..9075e25513df
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/nothreads/thread.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: thread.c,v 1.5 2007/06/19 23:47:18 tbox Exp $ */
+
+#include <config.h>
+
+#include <isc/thread.h>
+#include <isc/util.h>
+
+void
+isc_thread_setconcurrency(unsigned int level) {
+ UNUSED(level);
+}
diff --git a/contrib/ntp/libntp/lib/isc/ondestroy.c b/contrib/ntp/libntp/lib/isc/ondestroy.c
new file mode 100644
index 000000000000..32a75e1f9488
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/ondestroy.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ondestroy.c,v 1.16 2007/06/19 23:47:17 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include <isc/event.h>
+#include <isc/magic.h>
+#include <isc/ondestroy.h>
+#include <isc/task.h>
+#include <isc/util.h>
+
+#define ONDESTROY_MAGIC ISC_MAGIC('D', 'e', 'S', 't')
+#define VALID_ONDESTROY(s) ISC_MAGIC_VALID(s, ONDESTROY_MAGIC)
+
+void
+isc_ondestroy_init(isc_ondestroy_t *ondest) {
+ ondest->magic = ONDESTROY_MAGIC;
+ ISC_LIST_INIT(ondest->events);
+}
+
+isc_result_t
+isc_ondestroy_register(isc_ondestroy_t *ondest, isc_task_t *task,
+ isc_event_t **eventp)
+{
+ isc_event_t *theevent;
+ isc_task_t *thetask = NULL;
+
+ REQUIRE(VALID_ONDESTROY(ondest));
+ REQUIRE(task != NULL);
+ REQUIRE(eventp != NULL);
+
+ theevent = *eventp;
+
+ REQUIRE(theevent != NULL);
+
+ isc_task_attach(task, &thetask);
+
+ theevent->ev_sender = thetask;
+
+ ISC_LIST_APPEND(ondest->events, theevent, ev_link);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_ondestroy_notify(isc_ondestroy_t *ondest, void *sender) {
+ isc_event_t *eventp;
+ isc_task_t *task;
+
+ REQUIRE(VALID_ONDESTROY(ondest));
+
+ eventp = ISC_LIST_HEAD(ondest->events);
+ while (eventp != NULL) {
+ ISC_LIST_UNLINK(ondest->events, eventp, ev_link);
+
+ task = eventp->ev_sender;
+ eventp->ev_sender = sender;
+
+ isc_task_sendanddetach(&task, &eventp);
+
+ eventp = ISC_LIST_HEAD(ondest->events);
+ }
+}
+
+
diff --git a/contrib/ntp/libntp/lib/isc/pthreads/condition.c b/contrib/ntp/libntp/lib/isc/pthreads/condition.c
new file mode 100644
index 000000000000..50281a2b87cb
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/pthreads/condition.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: condition.c,v 1.36 2007/06/19 23:47:18 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <errno.h>
+
+#include <isc/condition.h>
+#include <isc/msgs.h>
+#include <isc/strerror.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+isc_result_t
+isc_condition_waituntil(isc_condition_t *c, isc_mutex_t *m, isc_time_t *t) {
+ int presult;
+ isc_result_t result;
+ struct timespec ts;
+ char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(c != NULL && m != NULL && t != NULL);
+
+ /*
+ * POSIX defines a timespec's tv_sec as time_t.
+ */
+ result = isc_time_secondsastimet(t, &ts.tv_sec);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ /*!
+ * POSIX defines a timespec's tv_nsec as long. isc_time_nanoseconds
+ * ensures its return value is < 1 billion, which will fit in a long.
+ */
+ ts.tv_nsec = (long)isc_time_nanoseconds(t);
+
+ do {
+#if ISC_MUTEX_PROFILE
+ presult = pthread_cond_timedwait(c, &m->mutex, &ts);
+#else
+ presult = pthread_cond_timedwait(c, m, &ts);
+#endif
+ if (presult == 0)
+ return (ISC_R_SUCCESS);
+ if (presult == ETIMEDOUT)
+ return (ISC_R_TIMEDOUT);
+ } while (presult == EINTR);
+
+ isc__strerror(presult, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "pthread_cond_timedwait() %s %s",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_RETURNED, "returned"),
+ strbuf);
+ return (ISC_R_UNEXPECTED);
+}
diff --git a/contrib/ntp/libntp/lib/isc/pthreads/include/isc/condition.h b/contrib/ntp/libntp/lib/isc/pthreads/include/isc/condition.h
new file mode 100644
index 000000000000..04a61185d17e
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/pthreads/include/isc/condition.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: condition.h,v 1.26 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_CONDITION_H
+#define ISC_CONDITION_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/result.h>
+#include <isc/types.h>
+
+typedef pthread_cond_t isc_condition_t;
+
+#define isc_condition_init(cp) \
+ ((pthread_cond_init((cp), NULL) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+
+#if ISC_MUTEX_PROFILE
+#define isc_condition_wait(cp, mp) \
+ ((pthread_cond_wait((cp), &((mp)->mutex)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#else
+#define isc_condition_wait(cp, mp) \
+ ((pthread_cond_wait((cp), (mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#endif
+
+#define isc_condition_signal(cp) \
+ ((pthread_cond_signal((cp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+
+#define isc_condition_broadcast(cp) \
+ ((pthread_cond_broadcast((cp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+
+#define isc_condition_destroy(cp) \
+ ((pthread_cond_destroy((cp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, isc_time_t *);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_CONDITION_H */
diff --git a/contrib/ntp/libntp/lib/isc/pthreads/include/isc/mutex.h b/contrib/ntp/libntp/lib/isc/pthreads/include/isc/mutex.h
new file mode 100644
index 000000000000..dd7d32687229
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/pthreads/include/isc/mutex.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mutex.h,v 1.30 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_MUTEX_H
+#define ISC_MUTEX_H 1
+
+/*! \file */
+
+#include <pthread.h>
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/result.h> /* for ISC_R_ codes */
+
+ISC_LANG_BEGINDECLS
+
+/*!
+ * Supply mutex attributes that enable deadlock detection
+ * (helpful when debugging). This is system dependent and
+ * currently only supported on NetBSD.
+ */
+#if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK)
+extern pthread_mutexattr_t isc__mutex_attrs;
+#define ISC__MUTEX_ATTRS &isc__mutex_attrs
+#else
+#define ISC__MUTEX_ATTRS NULL
+#endif
+
+/* XXX We could do fancier error handling... */
+
+/*!
+ * Define ISC_MUTEX_PROFILE to turn on profiling of mutexes by line. When
+ * enabled, isc_mutex_stats() can be used to print a table showing the
+ * number of times each type of mutex was locked and the amount of time
+ * waiting to obtain the lock.
+ */
+#ifndef ISC_MUTEX_PROFILE
+#define ISC_MUTEX_PROFILE 0
+#endif
+
+#if ISC_MUTEX_PROFILE
+typedef struct isc_mutexstats isc_mutexstats_t;
+
+typedef struct {
+ pthread_mutex_t mutex; /*%< The actual mutex. */
+ isc_mutexstats_t * stats; /*%< Mutex statistics. */
+} isc_mutex_t;
+#else
+typedef pthread_mutex_t isc_mutex_t;
+#endif
+
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_init(mp) \
+ isc_mutex_init_profile((mp), __FILE__, __LINE__)
+#else
+#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
+#define isc_mutex_init(mp) \
+ isc_mutex_init_errcheck((mp))
+#else
+#define isc_mutex_init(mp) \
+ isc__mutex_init((mp), __FILE__, __LINE__)
+isc_result_t isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line);
+#endif
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_lock(mp) \
+ isc_mutex_lock_profile((mp), __FILE__, __LINE__)
+#else
+#define isc_mutex_lock(mp) \
+ ((pthread_mutex_lock((mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_unlock(mp) \
+ isc_mutex_unlock_profile((mp), __FILE__, __LINE__)
+#else
+#define isc_mutex_unlock(mp) \
+ ((pthread_mutex_unlock((mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_trylock(mp) \
+ ((pthread_mutex_trylock((&(mp)->mutex)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_LOCKBUSY)
+#else
+#define isc_mutex_trylock(mp) \
+ ((pthread_mutex_trylock((mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_LOCKBUSY)
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_destroy(mp) \
+ ((pthread_mutex_destroy((&(mp)->mutex)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#else
+#define isc_mutex_destroy(mp) \
+ ((pthread_mutex_destroy((mp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+#endif
+
+#if ISC_MUTEX_PROFILE
+#define isc_mutex_stats(fp) isc_mutex_statsprofile(fp);
+#else
+#define isc_mutex_stats(fp)
+#endif
+
+#if ISC_MUTEX_PROFILE
+
+isc_result_t
+isc_mutex_init_profile(isc_mutex_t *mp, const char * _file, int _line);
+isc_result_t
+isc_mutex_lock_profile(isc_mutex_t *mp, const char * _file, int _line);
+isc_result_t
+isc_mutex_unlock_profile(isc_mutex_t *mp, const char * _file, int _line);
+
+void
+isc_mutex_statsprofile(FILE *fp);
+
+isc_result_t
+isc_mutex_init_errcheck(isc_mutex_t *mp);
+
+#endif /* ISC_MUTEX_PROFILE */
+
+ISC_LANG_ENDDECLS
+#endif /* ISC_MUTEX_H */
diff --git a/contrib/ntp/libntp/lib/isc/pthreads/include/isc/once.h b/contrib/ntp/libntp/lib/isc/pthreads/include/isc/once.h
new file mode 100644
index 000000000000..31d76fb6f2b7
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/pthreads/include/isc/once.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: once.h,v 1.13 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_ONCE_H
+#define ISC_ONCE_H 1
+
+/*! \file */
+
+#include <pthread.h>
+
+#include <isc/platform.h>
+#include <isc/result.h>
+
+typedef pthread_once_t isc_once_t;
+
+#ifdef ISC_PLATFORM_BRACEPTHREADONCEINIT
+/*!
+ * This accomodates systems that define PTHRAD_ONCE_INIT improperly.
+ */
+#define ISC_ONCE_INIT { PTHREAD_ONCE_INIT }
+#else
+/*!
+ * This is the usual case.
+ */
+#define ISC_ONCE_INIT PTHREAD_ONCE_INIT
+#endif
+
+/* XXX We could do fancier error handling... */
+
+#define isc_once_do(op, f) \
+ ((pthread_once((op), (f)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+
+#endif /* ISC_ONCE_H */
diff --git a/contrib/ntp/libntp/lib/isc/pthreads/include/isc/thread.h b/contrib/ntp/libntp/lib/isc/pthreads/include/isc/thread.h
new file mode 100644
index 000000000000..7dcc9527cf7b
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/pthreads/include/isc/thread.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: thread.h,v 1.26 2007/06/19 23:47:18 tbox Exp $ */
+
+#ifndef ISC_THREAD_H
+#define ISC_THREAD_H 1
+
+/*! \file */
+
+#include <pthread.h>
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+ISC_LANG_BEGINDECLS
+
+typedef pthread_t isc_thread_t;
+typedef void * isc_threadresult_t;
+typedef void * isc_threadarg_t;
+typedef isc_threadresult_t (*isc_threadfunc_t)(isc_threadarg_t);
+typedef pthread_key_t isc_thread_key_t;
+
+isc_result_t
+isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *);
+
+void
+isc_thread_setconcurrency(unsigned int level);
+
+/* XXX We could do fancier error handling... */
+
+#define isc_thread_join(t, rp) \
+ ((pthread_join((t), (rp)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED)
+
+#define isc_thread_self \
+ (unsigned long)pthread_self
+
+#define isc_thread_key_create pthread_key_create
+#define isc_thread_key_getspecific pthread_getspecific
+#define isc_thread_key_setspecific pthread_setspecific
+#define isc_thread_key_delete pthread_key_delete
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_THREAD_H */
diff --git a/contrib/ntp/libntp/lib/isc/pthreads/mutex.c b/contrib/ntp/libntp/lib/isc/pthreads/mutex.c
new file mode 100644
index 000000000000..62ad540a7e17
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/pthreads/mutex.c
@@ -0,0 +1,284 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mutex.c,v 1.18 2011/01/04 23:47:14 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <errno.h>
+
+#include <isc/mutex.h>
+#include <isc/util.h>
+#include <isc/strerror.h>
+
+#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
+
+/*@{*/
+/*% Operations on timevals; adapted from FreeBSD's sys/time.h */
+#define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
+#define timevaladd(vvp, uvp) \
+ do { \
+ (vvp)->tv_sec += (uvp)->tv_sec; \
+ (vvp)->tv_usec += (uvp)->tv_usec; \
+ if ((vvp)->tv_usec >= 1000000) { \
+ (vvp)->tv_sec++; \
+ (vvp)->tv_usec -= 1000000; \
+ } \
+ } while (0)
+#define timevalsub(vvp, uvp) \
+ do { \
+ (vvp)->tv_sec -= (uvp)->tv_sec; \
+ (vvp)->tv_usec -= (uvp)->tv_usec; \
+ if ((vvp)->tv_usec < 0) { \
+ (vvp)->tv_sec--; \
+ (vvp)->tv_usec += 1000000; \
+ } \
+ } while (0)
+
+/*@}*/
+
+#define ISC_MUTEX_MAX_LOCKERS 32
+
+typedef struct {
+ const char * file;
+ int line;
+ unsigned count;
+ struct timeval locked_total;
+ struct timeval wait_total;
+} isc_mutexlocker_t;
+
+struct isc_mutexstats {
+ const char * file; /*%< File mutex was created in. */
+ int line; /*%< Line mutex was created on. */
+ unsigned count;
+ struct timeval lock_t;
+ struct timeval locked_total;
+ struct timeval wait_total;
+ isc_mutexlocker_t * cur_locker;
+ isc_mutexlocker_t lockers[ISC_MUTEX_MAX_LOCKERS];
+};
+
+#ifndef ISC_MUTEX_PROFTABLESIZE
+#define ISC_MUTEX_PROFTABLESIZE (1024 * 1024)
+#endif
+static isc_mutexstats_t stats[ISC_MUTEX_PROFTABLESIZE];
+static int stats_next = 0;
+static isc_boolean_t stats_init = ISC_FALSE;
+static pthread_mutex_t statslock = PTHREAD_MUTEX_INITIALIZER;
+
+
+isc_result_t
+isc_mutex_init_profile(isc_mutex_t *mp, const char *file, int line) {
+ int i, err;
+
+ err = pthread_mutex_init(&mp->mutex, NULL);
+ if (err == ENOMEM)
+ return (ISC_R_NOMEMORY);
+ if (err != 0)
+ return (ISC_R_UNEXPECTED);
+
+ RUNTIME_CHECK(pthread_mutex_lock(&statslock) == 0);
+
+ if (stats_init == ISC_FALSE)
+ stats_init = ISC_TRUE;
+
+ /*
+ * If all statistics entries have been used, give up and trigger an
+ * assertion failure. There would be no other way to deal with this
+ * because we'd like to keep record of all locks for the purpose of
+ * debugging and the number of necessary locks is unpredictable.
+ * If this failure is triggered while debugging, named should be
+ * rebuilt with an increased ISC_MUTEX_PROFTABLESIZE.
+ */
+ RUNTIME_CHECK(stats_next < ISC_MUTEX_PROFTABLESIZE);
+ mp->stats = &stats[stats_next++];
+
+ RUNTIME_CHECK(pthread_mutex_unlock(&statslock) == 0);
+
+ mp->stats->file = file;
+ mp->stats->line = line;
+ mp->stats->count = 0;
+ timevalclear(&mp->stats->locked_total);
+ timevalclear(&mp->stats->wait_total);
+ for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) {
+ mp->stats->lockers[i].file = NULL;
+ mp->stats->lockers[i].line = 0;
+ mp->stats->lockers[i].count = 0;
+ timevalclear(&mp->stats->lockers[i].locked_total);
+ timevalclear(&mp->stats->lockers[i].wait_total);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_mutex_lock_profile(isc_mutex_t *mp, const char *file, int line) {
+ struct timeval prelock_t;
+ struct timeval postlock_t;
+ isc_mutexlocker_t *locker = NULL;
+ int i;
+
+ gettimeofday(&prelock_t, NULL);
+
+ if (pthread_mutex_lock(&mp->mutex) != 0)
+ return (ISC_R_UNEXPECTED);
+
+ gettimeofday(&postlock_t, NULL);
+ mp->stats->lock_t = postlock_t;
+
+ timevalsub(&postlock_t, &prelock_t);
+
+ mp->stats->count++;
+ timevaladd(&mp->stats->wait_total, &postlock_t);
+
+ for (i = 0; i < ISC_MUTEX_MAX_LOCKERS; i++) {
+ if (mp->stats->lockers[i].file == NULL) {
+ locker = &mp->stats->lockers[i];
+ locker->file = file;
+ locker->line = line;
+ break;
+ } else if (mp->stats->lockers[i].file == file &&
+ mp->stats->lockers[i].line == line) {
+ locker = &mp->stats->lockers[i];
+ break;
+ }
+ }
+
+ if (locker != NULL) {
+ locker->count++;
+ timevaladd(&locker->wait_total, &postlock_t);
+ }
+
+ mp->stats->cur_locker = locker;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_mutex_unlock_profile(isc_mutex_t *mp, const char *file, int line) {
+ struct timeval unlock_t;
+
+ UNUSED(file);
+ UNUSED(line);
+
+ if (mp->stats->cur_locker != NULL) {
+ gettimeofday(&unlock_t, NULL);
+ timevalsub(&unlock_t, &mp->stats->lock_t);
+ timevaladd(&mp->stats->locked_total, &unlock_t);
+ timevaladd(&mp->stats->cur_locker->locked_total, &unlock_t);
+ mp->stats->cur_locker = NULL;
+ }
+
+ return ((pthread_mutex_unlock((&mp->mutex)) == 0) ? \
+ ISC_R_SUCCESS : ISC_R_UNEXPECTED);
+}
+
+
+void
+isc_mutex_statsprofile(FILE *fp) {
+ isc_mutexlocker_t *locker;
+ int i, j;
+
+ fprintf(fp, "Mutex stats (in us)\n");
+ for (i = 0; i < stats_next; i++) {
+ fprintf(fp, "%-12s %4d: %10u %lu.%06lu %lu.%06lu %5d\n",
+ stats[i].file, stats[i].line, stats[i].count,
+ stats[i].locked_total.tv_sec,
+ stats[i].locked_total.tv_usec,
+ stats[i].wait_total.tv_sec,
+ stats[i].wait_total.tv_usec,
+ i);
+ for (j = 0; j < ISC_MUTEX_MAX_LOCKERS; j++) {
+ locker = &stats[i].lockers[j];
+ if (locker->file == NULL)
+ continue;
+ fprintf(fp, " %-11s %4d: %10u %lu.%06lu %lu.%06lu %5d\n",
+ locker->file, locker->line, locker->count,
+ locker->locked_total.tv_sec,
+ locker->locked_total.tv_usec,
+ locker->wait_total.tv_sec,
+ locker->wait_total.tv_usec,
+ i);
+ }
+ }
+}
+
+#endif /* ISC_MUTEX_PROFILE */
+
+#if ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)
+isc_result_t
+isc_mutex_init_errcheck(isc_mutex_t *mp)
+{
+ pthread_mutexattr_t attr;
+ int err;
+
+ if (pthread_mutexattr_init(&attr) != 0)
+ return (ISC_R_UNEXPECTED);
+
+ if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK) != 0) {
+ pthread_mutexattr_destroy(&attr);
+ return (ISC_R_UNEXPECTED);
+ }
+
+ err = pthread_mutex_init(mp, &attr) != 0)
+ pthread_mutexattr_destroy(&attr);
+ if (err == ENOMEM)
+ return (ISC_R_NOMEMORY);
+ return ((err == 0) ? ISC_R_SUCCESS : ISC_R_UNEXPECTED);
+}
+#endif
+
+#if ISC_MUTEX_DEBUG && defined(__NetBSD__) && defined(PTHREAD_MUTEX_ERRORCHECK)
+pthread_mutexattr_t isc__mutex_attrs = {
+ PTHREAD_MUTEX_ERRORCHECK, /* m_type */
+ 0 /* m_flags, which appears to be unused. */
+};
+#endif
+
+#if !(ISC_MUTEX_DEBUG && defined(PTHREAD_MUTEX_ERRORCHECK)) && !ISC_MUTEX_PROFILE
+isc_result_t
+isc__mutex_init(isc_mutex_t *mp, const char *file, unsigned int line) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc_result_t result = ISC_R_SUCCESS;
+ int err;
+
+ err = pthread_mutex_init(mp, ISC__MUTEX_ATTRS);
+ if (err == ENOMEM)
+ return (ISC_R_NOMEMORY);
+ if (err != 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(file, line, "isc_mutex_init() failed: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ }
+ return (result);
+}
+#endif
diff --git a/contrib/ntp/libntp/lib/isc/pthreads/thread.c b/contrib/ntp/libntp/lib/isc/pthreads/thread.c
new file mode 100644
index 000000000000..4b5b4919b2b0
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/pthreads/thread.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: thread.c,v 1.17 2007/06/19 23:47:18 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isc/thread.h>
+#include <isc/util.h>
+
+#ifndef THREAD_MINSTACKSIZE
+#define THREAD_MINSTACKSIZE (64U * 1024)
+#endif
+
+isc_result_t
+isc_thread_create(isc_threadfunc_t func, isc_threadarg_t arg,
+ isc_thread_t *thread)
+{
+ pthread_attr_t attr;
+ size_t stacksize;
+ int ret;
+
+ pthread_attr_init(&attr);
+
+#if defined(HAVE_PTHREAD_ATTR_GETSTACKSIZE) && \
+ defined(HAVE_PTHREAD_ATTR_SETSTACKSIZE)
+ ret = pthread_attr_getstacksize(&attr, &stacksize);
+ if (ret != 0)
+ return (ISC_R_UNEXPECTED);
+
+ if (stacksize < THREAD_MINSTACKSIZE) {
+ ret = pthread_attr_setstacksize(&attr, THREAD_MINSTACKSIZE);
+ if (ret != 0)
+ return (ISC_R_UNEXPECTED);
+ }
+#endif
+
+#if defined(PTHREAD_SCOPE_SYSTEM) && defined(NEED_PTHREAD_SCOPE_SYSTEM)
+ ret = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+ if (ret != 0)
+ return (ISC_R_UNEXPECTED);
+#endif
+
+ ret = pthread_create(thread, &attr, func, arg);
+ if (ret != 0)
+ return (ISC_R_UNEXPECTED);
+
+ pthread_attr_destroy(&attr);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_thread_setconcurrency(unsigned int level) {
+#if defined(CALL_PTHREAD_SETCONCURRENCY)
+ (void)pthread_setconcurrency(level);
+#else
+ UNUSED(level);
+#endif
+}
diff --git a/contrib/ntp/libntp/lib/isc/random.c b/contrib/ntp/libntp/lib/isc/random.c
new file mode 100644
index 000000000000..c433f478a837
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/random.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: random.c,v 1.28 2009/07/16 05:52:46 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <time.h> /* Required for time(). */
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/random.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+static isc_once_t once = ISC_ONCE_INIT;
+
+static void
+initialize_rand(void)
+{
+#ifndef HAVE_ARC4RANDOM
+ unsigned int pid = getpid();
+
+ /*
+ * The low bits of pid generally change faster.
+ * Xor them with the high bits of time which change slowly.
+ */
+ pid = ((pid << 16) & 0xffff0000) | ((pid >> 16) & 0xffff);
+
+ srand(time(NULL) ^ pid);
+#endif
+}
+
+static void
+initialize(void)
+{
+ RUNTIME_CHECK(isc_once_do(&once, initialize_rand) == ISC_R_SUCCESS);
+}
+
+void
+isc_random_seed(isc_uint32_t seed)
+{
+ initialize();
+
+#ifndef HAVE_ARC4RANDOM
+ srand(seed);
+#endif
+}
+
+void
+isc_random_get(isc_uint32_t *val)
+{
+ REQUIRE(val != NULL);
+
+ initialize();
+
+#ifndef HAVE_ARC4RANDOM
+ /*
+ * rand()'s lower bits are not random.
+ * rand()'s upper bit is zero.
+ */
+#if RAND_MAX >= 0xfffff
+ /* We have at least 20 bits. Use lower 16 excluding lower most 4 */
+ *val = ((rand() >> 4) & 0xffff) | ((rand() << 12) & 0xffff0000);
+#elif RAND_MAX >= 0x7fff
+ /* We have at least 15 bits. Use lower 10/11 excluding lower most 4 */
+ *val = ((rand() >> 4) & 0x000007ff) | ((rand() << 7) & 0x003ff800) |
+ ((rand() << 18) & 0xffc00000);
+#else
+#error RAND_MAX is too small
+#endif
+#else
+ *val = arc4random();
+#endif
+}
+
+isc_uint32_t
+isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter) {
+ isc_uint32_t rnd;
+
+ REQUIRE(jitter < max || (jitter == 0 && max == 0));
+
+ if (jitter == 0)
+ return (max);
+
+ isc_random_get(&rnd);
+ return (max - rnd % jitter);
+}
diff --git a/contrib/ntp/libntp/lib/isc/result.c b/contrib/ntp/libntp/lib/isc/result.c
new file mode 100644
index 000000000000..da57272dfc27
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/result.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stddef.h>
+#include <stdlib.h>
+
+#include <isc/lib.h>
+#include <isc/msgs.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/resultclass.h>
+#include <isc/util.h>
+
+typedef struct resulttable {
+ unsigned int base;
+ unsigned int last;
+ const char ** text;
+ isc_msgcat_t * msgcat;
+ int set;
+ ISC_LINK(struct resulttable) link;
+} resulttable;
+
+static const char *text[ISC_R_NRESULTS] = {
+ "success", /*%< 0 */
+ "out of memory", /*%< 1 */
+ "timed out", /*%< 2 */
+ "no available threads", /*%< 3 */
+ "address not available", /*%< 4 */
+ "address in use", /*%< 5 */
+ "permission denied", /*%< 6 */
+ "no pending connections", /*%< 7 */
+ "network unreachable", /*%< 8 */
+ "host unreachable", /*%< 9 */
+ "network down", /*%< 10 */
+ "host down", /*%< 11 */
+ "connection refused", /*%< 12 */
+ "not enough free resources", /*%< 13 */
+ "end of file", /*%< 14 */
+ "socket already bound", /*%< 15 */
+ "reload", /*%< 16 */
+ "lock busy", /*%< 17 */
+ "already exists", /*%< 18 */
+ "ran out of space", /*%< 19 */
+ "operation canceled", /*%< 20 */
+ "socket is not bound", /*%< 21 */
+ "shutting down", /*%< 22 */
+ "not found", /*%< 23 */
+ "unexpected end of input", /*%< 24 */
+ "failure", /*%< 25 */
+ "I/O error", /*%< 26 */
+ "not implemented", /*%< 27 */
+ "unbalanced parentheses", /*%< 28 */
+ "no more", /*%< 29 */
+ "invalid file", /*%< 30 */
+ "bad base64 encoding", /*%< 31 */
+ "unexpected token", /*%< 32 */
+ "quota reached", /*%< 33 */
+ "unexpected error", /*%< 34 */
+ "already running", /*%< 35 */
+ "ignore", /*%< 36 */
+ "address mask not contiguous", /*%< 37 */
+ "file not found", /*%< 38 */
+ "file already exists", /*%< 39 */
+ "socket is not connected", /*%< 40 */
+ "out of range", /*%< 41 */
+ "out of entropy", /*%< 42 */
+ "invalid use of multicast address", /*%< 43 */
+ "not a file", /*%< 44 */
+ "not a directory", /*%< 45 */
+ "queue is full", /*%< 46 */
+ "address family mismatch", /*%< 47 */
+ "address family not supported", /*%< 48 */
+ "bad hex encoding", /*%< 49 */
+ "too many open files", /*%< 50 */
+ "not blocking", /*%< 51 */
+ "unbalanced quotes", /*%< 52 */
+ "operation in progress", /*%< 53 */
+ "connection reset", /*%< 54 */
+ "soft quota reached", /*%< 55 */
+ "not a valid number", /*%< 56 */
+ "disabled", /*%< 57 */
+ "max size", /*%< 58 */
+ "invalid address format", /*%< 59 */
+ "bad base32 encoding", /*%< 60 */
+ "unset", /*%< 61 */
+};
+
+#define ISC_RESULT_RESULTSET 2
+#define ISC_RESULT_UNAVAILABLESET 3
+
+static isc_once_t once = ISC_ONCE_INIT;
+static ISC_LIST(resulttable) tables;
+static isc_mutex_t lock;
+
+static isc_result_t
+register_table(unsigned int base, unsigned int nresults, const char **txt,
+ isc_msgcat_t *msgcat, int set)
+{
+ resulttable *table;
+
+ REQUIRE(base % ISC_RESULTCLASS_SIZE == 0);
+ REQUIRE(nresults <= ISC_RESULTCLASS_SIZE);
+ REQUIRE(txt != NULL);
+
+ /*
+ * We use malloc() here because we we want to be able to use
+ * isc_result_totext() even if there is no memory context.
+ */
+ table = malloc(sizeof(*table));
+ if (table == NULL)
+ return (ISC_R_NOMEMORY);
+ table->base = base;
+ table->last = base + nresults - 1;
+ table->text = txt;
+ table->msgcat = msgcat;
+ table->set = set;
+ ISC_LINK_INIT(table, link);
+
+ LOCK(&lock);
+
+ ISC_LIST_APPEND(tables, table, link);
+
+ UNLOCK(&lock);
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+initialize_action(void) {
+ isc_result_t result;
+
+ RUNTIME_CHECK(isc_mutex_init(&lock) == ISC_R_SUCCESS);
+ ISC_LIST_INIT(tables);
+
+ result = register_table(ISC_RESULTCLASS_ISC, ISC_R_NRESULTS, text,
+ isc_msgcat, ISC_RESULT_RESULTSET);
+ if (result != ISC_R_SUCCESS)
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "register_table() %s: %u",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"),
+ result);
+}
+
+static void
+initialize(void) {
+ isc_lib_initmsgcat();
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+}
+
+const char *
+isc_result_totext(isc_result_t result) {
+ resulttable *table;
+ const char *txt, *default_text;
+ int idx;
+
+ initialize();
+
+ LOCK(&lock);
+
+ txt = NULL;
+ for (table = ISC_LIST_HEAD(tables);
+ table != NULL;
+ table = ISC_LIST_NEXT(table, link)) {
+ if (result >= table->base && result <= table->last) {
+ idx = (int)(result - table->base);
+ default_text = table->text[idx];
+ /*
+ * Note: we use 'idx + 1' as the message number
+ * instead of idx because isc_msgcat_get() requires
+ * the message number to be > 0.
+ */
+ txt = isc_msgcat_get(table->msgcat, table->set,
+ idx + 1, default_text);
+ break;
+ }
+ }
+ if (txt == NULL)
+ txt = isc_msgcat_get(isc_msgcat, ISC_RESULT_UNAVAILABLESET,
+ 1, "(result code text not available)");
+
+ UNLOCK(&lock);
+
+ return (txt);
+}
+
+isc_result_t
+isc_result_register(unsigned int base, unsigned int nresults,
+ const char **txt, isc_msgcat_t *msgcat, int set)
+{
+ initialize();
+
+ return (register_table(base, nresults, txt, msgcat, set));
+}
diff --git a/contrib/ntp/libntp/lib/isc/sha1.c b/contrib/ntp/libntp/lib/isc/sha1.c
new file mode 100644
index 000000000000..cce96036045f
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/sha1.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/* $NetBSD: sha1.c,v 1.5 2000/01/22 22:19:14 mycroft Exp $ */
+/* $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ */
+
+/*! \file
+ * SHA-1 in C
+ * \author By Steve Reid <steve@edmweb.com>
+ * 100% Public Domain
+ * \verbatim
+ * Test Vectors (from FIPS PUB 180-1)
+ * "abc"
+ * A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+ * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+ * 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+ * A million repetitions of "a"
+ * 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+ * \endverbatim
+ */
+
+#include "config.h"
+
+#include <isc/assertions.h>
+#include <isc/platform.h>
+#include <isc/sha1.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#ifdef ISC_PLATFORM_OPENSSLHASH
+
+void
+isc_sha1_init(isc_sha1_t *context)
+{
+ INSIST(context != NULL);
+
+ EVP_DigestInit(context, EVP_sha1());
+}
+
+void
+isc_sha1_invalidate(isc_sha1_t *context) {
+ EVP_MD_CTX_cleanup(context);
+}
+
+void
+isc_sha1_update(isc_sha1_t *context, const unsigned char *data,
+ unsigned int len)
+{
+ INSIST(context != 0);
+ INSIST(data != 0);
+
+ EVP_DigestUpdate(context, (const void *) data, (size_t) len);
+}
+
+void
+isc_sha1_final(isc_sha1_t *context, unsigned char *digest) {
+ INSIST(digest != 0);
+ INSIST(context != 0);
+
+ EVP_DigestFinal(context, digest, NULL);
+}
+
+#else
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/*@{*/
+/*!
+ * blk0() and blk() perform the initial expand.
+ * I got the idea of expanding during the round function from SSLeay
+ */
+#if !defined(WORDS_BIGENDIAN)
+# define blk0(i) \
+ (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) \
+ | (rol(block->l[i], 8) & 0x00FF00FF))
+#else
+# define blk0(i) block->l[i]
+#endif
+#define blk(i) \
+ (block->l[i & 15] = rol(block->l[(i + 13) & 15] \
+ ^ block->l[(i + 8) & 15] \
+ ^ block->l[(i + 2) & 15] \
+ ^ block->l[i & 15], 1))
+
+/*@}*/
+/*@{*/
+/*!
+ * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
+ */
+#define R0(v,w,x,y,z,i) \
+ z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
+ w = rol(w, 30);
+#define R1(v,w,x,y,z,i) \
+ z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
+ w = rol(w, 30);
+#define R2(v,w,x,y,z,i) \
+ z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); \
+ w = rol(w, 30);
+#define R3(v,w,x,y,z,i) \
+ z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
+ w = rol(w, 30);
+#define R4(v,w,x,y,z,i) \
+ z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
+ w = rol(w, 30);
+
+/*@}*/
+
+typedef union {
+ unsigned char c[64];
+ unsigned int l[16];
+} CHAR64LONG16;
+
+#ifdef __sparc_v9__
+static void do_R01(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c,
+ isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *);
+static void do_R2(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c,
+ isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *);
+static void do_R3(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c,
+ isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *);
+static void do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c,
+ isc_uint32_t *d, isc_uint32_t *e, CHAR64LONG16 *);
+
+#define nR0(v,w,x,y,z,i) R0(*v,*w,*x,*y,*z,i)
+#define nR1(v,w,x,y,z,i) R1(*v,*w,*x,*y,*z,i)
+#define nR2(v,w,x,y,z,i) R2(*v,*w,*x,*y,*z,i)
+#define nR3(v,w,x,y,z,i) R3(*v,*w,*x,*y,*z,i)
+#define nR4(v,w,x,y,z,i) R4(*v,*w,*x,*y,*z,i)
+
+static void
+do_R01(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
+ isc_uint32_t *e, CHAR64LONG16 *block)
+{
+ nR0(a,b,c,d,e, 0); nR0(e,a,b,c,d, 1); nR0(d,e,a,b,c, 2);
+ nR0(c,d,e,a,b, 3); nR0(b,c,d,e,a, 4); nR0(a,b,c,d,e, 5);
+ nR0(e,a,b,c,d, 6); nR0(d,e,a,b,c, 7); nR0(c,d,e,a,b, 8);
+ nR0(b,c,d,e,a, 9); nR0(a,b,c,d,e,10); nR0(e,a,b,c,d,11);
+ nR0(d,e,a,b,c,12); nR0(c,d,e,a,b,13); nR0(b,c,d,e,a,14);
+ nR0(a,b,c,d,e,15); nR1(e,a,b,c,d,16); nR1(d,e,a,b,c,17);
+ nR1(c,d,e,a,b,18); nR1(b,c,d,e,a,19);
+}
+
+static void
+do_R2(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
+ isc_uint32_t *e, CHAR64LONG16 *block)
+{
+ nR2(a,b,c,d,e,20); nR2(e,a,b,c,d,21); nR2(d,e,a,b,c,22);
+ nR2(c,d,e,a,b,23); nR2(b,c,d,e,a,24); nR2(a,b,c,d,e,25);
+ nR2(e,a,b,c,d,26); nR2(d,e,a,b,c,27); nR2(c,d,e,a,b,28);
+ nR2(b,c,d,e,a,29); nR2(a,b,c,d,e,30); nR2(e,a,b,c,d,31);
+ nR2(d,e,a,b,c,32); nR2(c,d,e,a,b,33); nR2(b,c,d,e,a,34);
+ nR2(a,b,c,d,e,35); nR2(e,a,b,c,d,36); nR2(d,e,a,b,c,37);
+ nR2(c,d,e,a,b,38); nR2(b,c,d,e,a,39);
+}
+
+static void
+do_R3(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
+ isc_uint32_t *e, CHAR64LONG16 *block)
+{
+ nR3(a,b,c,d,e,40); nR3(e,a,b,c,d,41); nR3(d,e,a,b,c,42);
+ nR3(c,d,e,a,b,43); nR3(b,c,d,e,a,44); nR3(a,b,c,d,e,45);
+ nR3(e,a,b,c,d,46); nR3(d,e,a,b,c,47); nR3(c,d,e,a,b,48);
+ nR3(b,c,d,e,a,49); nR3(a,b,c,d,e,50); nR3(e,a,b,c,d,51);
+ nR3(d,e,a,b,c,52); nR3(c,d,e,a,b,53); nR3(b,c,d,e,a,54);
+ nR3(a,b,c,d,e,55); nR3(e,a,b,c,d,56); nR3(d,e,a,b,c,57);
+ nR3(c,d,e,a,b,58); nR3(b,c,d,e,a,59);
+}
+
+static void
+do_R4(isc_uint32_t *a, isc_uint32_t *b, isc_uint32_t *c, isc_uint32_t *d,
+ isc_uint32_t *e, CHAR64LONG16 *block)
+{
+ nR4(a,b,c,d,e,60); nR4(e,a,b,c,d,61); nR4(d,e,a,b,c,62);
+ nR4(c,d,e,a,b,63); nR4(b,c,d,e,a,64); nR4(a,b,c,d,e,65);
+ nR4(e,a,b,c,d,66); nR4(d,e,a,b,c,67); nR4(c,d,e,a,b,68);
+ nR4(b,c,d,e,a,69); nR4(a,b,c,d,e,70); nR4(e,a,b,c,d,71);
+ nR4(d,e,a,b,c,72); nR4(c,d,e,a,b,73); nR4(b,c,d,e,a,74);
+ nR4(a,b,c,d,e,75); nR4(e,a,b,c,d,76); nR4(d,e,a,b,c,77);
+ nR4(c,d,e,a,b,78); nR4(b,c,d,e,a,79);
+}
+#endif
+
+/*!
+ * Hash a single 512-bit block. This is the core of the algorithm.
+ */
+static void
+transform(isc_uint32_t state[5], const unsigned char buffer[64]) {
+ isc_uint32_t a, b, c, d, e;
+ CHAR64LONG16 *block;
+ CHAR64LONG16 workspace;
+
+ INSIST(buffer != NULL);
+ INSIST(state != NULL);
+
+ block = &workspace;
+ (void)memcpy(block, buffer, 64);
+
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+
+#ifdef __sparc_v9__
+ do_R01(&a, &b, &c, &d, &e, block);
+ do_R2(&a, &b, &c, &d, &e, block);
+ do_R3(&a, &b, &c, &d, &e, block);
+ do_R4(&a, &b, &c, &d, &e, block);
+#else
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
+ R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
+ R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
+ R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
+ R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
+ R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
+ R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
+ R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
+ R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
+ R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
+ R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
+ R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
+ R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
+ R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
+ R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
+ R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
+ R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
+ R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
+ R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
+ R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
+#endif
+
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+ /* Avoid compiler warnings */
+ POST(a); POST(b); POST(c); POST(d); POST(e);
+}
+
+
+/*!
+ * isc_sha1_init - Initialize new context
+ */
+void
+isc_sha1_init(isc_sha1_t *context)
+{
+ INSIST(context != NULL);
+
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = 0;
+ context->count[1] = 0;
+}
+
+void
+isc_sha1_invalidate(isc_sha1_t *context) {
+ memset(context, 0, sizeof(isc_sha1_t));
+}
+
+/*!
+ * Run your data through this.
+ */
+void
+isc_sha1_update(isc_sha1_t *context, const unsigned char *data,
+ unsigned int len)
+{
+ unsigned int i, j;
+
+ INSIST(context != 0);
+ INSIST(data != 0);
+
+ j = context->count[0];
+ if ((context->count[0] += len << 3) < j)
+ context->count[1] += (len >> 29) + 1;
+ j = (j >> 3) & 63;
+ if ((j + len) > 63) {
+ (void)memcpy(&context->buffer[j], data, (i = 64 - j));
+ transform(context->state, context->buffer);
+ for (; i + 63 < len; i += 64)
+ transform(context->state, &data[i]);
+ j = 0;
+ } else {
+ i = 0;
+ }
+
+ (void)memcpy(&context->buffer[j], &data[i], len - i);
+}
+
+
+/*!
+ * Add padding and return the message digest.
+ */
+
+static const unsigned char final_200 = 128;
+static const unsigned char final_0 = 0;
+
+void
+isc_sha1_final(isc_sha1_t *context, unsigned char *digest) {
+ unsigned int i;
+ unsigned char finalcount[8];
+
+ INSIST(digest != 0);
+ INSIST(context != 0);
+
+ for (i = 0; i < 8; i++) {
+ /* Endian independent */
+ finalcount[i] = (unsigned char)
+ ((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3 - (i & 3)) * 8)) & 255);
+ }
+
+ isc_sha1_update(context, &final_200, 1);
+ while ((context->count[0] & 504) != 448)
+ isc_sha1_update(context, &final_0, 1);
+ /* The next Update should cause a transform() */
+ isc_sha1_update(context, finalcount, 8);
+
+ if (digest) {
+ for (i = 0; i < 20; i++)
+ digest[i] = (unsigned char)
+ ((context->state[i >> 2]
+ >> ((3 - (i & 3)) * 8)) & 255);
+ }
+
+ memset(context, 0, sizeof(isc_sha1_t));
+}
+#endif
diff --git a/contrib/ntp/libntp/lib/isc/sockaddr.c b/contrib/ntp/libntp/lib/isc/sockaddr.c
new file mode 100644
index 000000000000..c6932d48f2bb
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/sockaddr.c
@@ -0,0 +1,510 @@
+/*
+ * Copyright (C) 2004-2007, 2010-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <isc/buffer.h>
+#include <isc/hash.h>
+#include <isc/msgs.h>
+#include <isc/netaddr.h>
+#include <isc/print.h>
+#include <isc/region.h>
+#include <isc/sockaddr.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+isc_boolean_t
+isc_sockaddr_equal(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
+ return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR|
+ ISC_SOCKADDR_CMPPORT|
+ ISC_SOCKADDR_CMPSCOPE));
+}
+
+isc_boolean_t
+isc_sockaddr_eqaddr(const isc_sockaddr_t *a, const isc_sockaddr_t *b) {
+ return (isc_sockaddr_compare(a, b, ISC_SOCKADDR_CMPADDR|
+ ISC_SOCKADDR_CMPSCOPE));
+}
+
+isc_boolean_t
+isc_sockaddr_compare(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int flags)
+{
+ REQUIRE(a != NULL && b != NULL);
+
+ if (a->length != b->length)
+ return (ISC_FALSE);
+
+ /*
+ * We don't just memcmp because the sin_zero field isn't always
+ * zero.
+ */
+
+ if (a->type.sa.sa_family != b->type.sa.sa_family)
+ return (ISC_FALSE);
+ switch (a->type.sa.sa_family) {
+ case AF_INET:
+ if ((flags & ISC_SOCKADDR_CMPADDR) != 0 &&
+ memcmp(&a->type.sin.sin_addr, &b->type.sin.sin_addr,
+ sizeof(a->type.sin.sin_addr)) != 0)
+ return (ISC_FALSE);
+ if ((flags & ISC_SOCKADDR_CMPPORT) != 0 &&
+ a->type.sin.sin_port != b->type.sin.sin_port)
+ return (ISC_FALSE);
+ break;
+ case AF_INET6:
+ if ((flags & ISC_SOCKADDR_CMPADDR) != 0 &&
+ memcmp(&a->type.sin6.sin6_addr, &b->type.sin6.sin6_addr,
+ sizeof(a->type.sin6.sin6_addr)) != 0)
+ return (ISC_FALSE);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ /*
+ * If ISC_SOCKADDR_CMPSCOPEZERO is set then don't return
+ * ISC_FALSE if one of the scopes in zero.
+ */
+ if ((flags & ISC_SOCKADDR_CMPSCOPE) != 0 &&
+ a->type.sin6.sin6_scope_id != b->type.sin6.sin6_scope_id &&
+ ((flags & ISC_SOCKADDR_CMPSCOPEZERO) == 0 ||
+ (a->type.sin6.sin6_scope_id != 0 &&
+ b->type.sin6.sin6_scope_id != 0)))
+ return (ISC_FALSE);
+#endif
+ if ((flags & ISC_SOCKADDR_CMPPORT) != 0 &&
+ a->type.sin6.sin6_port != b->type.sin6.sin6_port)
+ return (ISC_FALSE);
+ break;
+ default:
+ if (memcmp(&a->type, &b->type, a->length) != 0)
+ return (ISC_FALSE);
+ }
+ return (ISC_TRUE);
+}
+
+isc_boolean_t
+isc_sockaddr_eqaddrprefix(const isc_sockaddr_t *a, const isc_sockaddr_t *b,
+ unsigned int prefixlen)
+{
+ isc_netaddr_t na, nb;
+ isc_netaddr_fromsockaddr(&na, a);
+ isc_netaddr_fromsockaddr(&nb, b);
+ return (isc_netaddr_eqprefix(&na, &nb, prefixlen));
+}
+
+isc_result_t
+isc_sockaddr_totext(const isc_sockaddr_t *sockaddr, isc_buffer_t *target) {
+ isc_result_t result;
+ isc_netaddr_t netaddr;
+ char pbuf[sizeof("65000")];
+ unsigned int plen;
+ isc_region_t avail;
+
+ REQUIRE(sockaddr != NULL);
+
+ /*
+ * Do the port first, giving us the opportunity to check for
+ * unsupported address families before calling
+ * isc_netaddr_fromsockaddr().
+ */
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin.sin_port));
+ break;
+ case AF_INET6:
+ snprintf(pbuf, sizeof(pbuf), "%u", ntohs(sockaddr->type.sin6.sin6_port));
+ break;
+#ifdef ISC_PLAFORM_HAVESYSUNH
+ case AF_UNIX:
+ plen = (unsigned int)strlen(sockaddr->type.sunix.sun_path);
+ if (plen >= isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+
+ isc_buffer_putmem(target, sockaddr->type.sunix.sun_path, plen);
+
+ /*
+ * Null terminate after used region.
+ */
+ isc_buffer_availableregion(target, &avail);
+ INSIST(avail.length >= 1);
+ avail.base[0] = '\0';
+
+ return (ISC_R_SUCCESS);
+#endif
+ default:
+ return (ISC_R_FAILURE);
+ }
+
+ plen = (unsigned int)strlen(pbuf);
+ INSIST(plen < sizeof(pbuf));
+
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ result = isc_netaddr_totext(&netaddr, target);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ if (1 + plen + 1 > isc_buffer_availablelength(target))
+ return (ISC_R_NOSPACE);
+
+ isc_buffer_putmem(target, (const unsigned char *)"#", 1);
+ isc_buffer_putmem(target, (const unsigned char *)pbuf, plen);
+
+ /*
+ * Null terminate after used region.
+ */
+ isc_buffer_availableregion(target, &avail);
+ INSIST(avail.length >= 1);
+ avail.base[0] = '\0';
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_sockaddr_format(const isc_sockaddr_t *sa, char *array, unsigned int size) {
+ isc_result_t result;
+ isc_buffer_t buf;
+
+ if (size == 0U)
+ return;
+
+ isc_buffer_init(&buf, array, size);
+ result = isc_sockaddr_totext(sa, &buf);
+ if (result != ISC_R_SUCCESS) {
+ /*
+ * The message is the same as in netaddr.c.
+ */
+ snprintf(array, size,
+ "<%s %u>",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_NETADDR,
+ ISC_MSG_UNKNOWNADDR,
+ "unknown address, family"),
+ sa->type.sa.sa_family);
+ array[size - 1] = '\0';
+ }
+}
+
+unsigned int
+isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) {
+ unsigned int length = 0;
+ const unsigned char *s = NULL;
+ unsigned int h = 0;
+ unsigned int g;
+ unsigned int p = 0;
+ const struct in6_addr *in6;
+
+ REQUIRE(sockaddr != NULL);
+
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ s = (const unsigned char *)&sockaddr->type.sin.sin_addr;
+ p = ntohs(sockaddr->type.sin.sin_port);
+ length = sizeof(sockaddr->type.sin.sin_addr.s_addr);
+ break;
+ case AF_INET6:
+ in6 = &sockaddr->type.sin6.sin6_addr;
+ if (IN6_IS_ADDR_V4MAPPED(in6)) {
+ s = (const unsigned char *)&in6 + 12;
+ length = sizeof(sockaddr->type.sin.sin_addr.s_addr);
+ } else {
+ s = (const unsigned char *)in6;
+ length = sizeof(sockaddr->type.sin6.sin6_addr);
+ }
+ p = ntohs(sockaddr->type.sin6.sin6_port);
+ break;
+ default:
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "%s: %d",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_SOCKADDR,
+ ISC_MSG_UNKNOWNFAMILY,
+ "unknown address family"),
+ (int)sockaddr->type.sa.sa_family);
+ s = (const unsigned char *)&sockaddr->type;
+ length = sockaddr->length;
+ p = 0;
+ }
+
+ h = isc_hash_calc(s, length, ISC_TRUE);
+ if (!address_only) {
+ g = isc_hash_calc((const unsigned char *)&p, sizeof(p),
+ ISC_TRUE);
+ h = h ^ g; /* XXX: we should concatenate h and p first */
+ }
+
+ return (h);
+}
+
+void
+isc_sockaddr_any(isc_sockaddr_t *sockaddr)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin.sin_family = AF_INET;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin);
+#endif
+ sockaddr->type.sin.sin_addr.s_addr = INADDR_ANY;
+ sockaddr->type.sin.sin_port = 0;
+ sockaddr->length = sizeof(sockaddr->type.sin);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_any6(isc_sockaddr_t *sockaddr)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin6.sin6_family = AF_INET6;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
+#endif
+ sockaddr->type.sin6.sin6_addr = in6addr_any;
+ sockaddr->type.sin6.sin6_port = 0;
+ sockaddr->length = sizeof(sockaddr->type.sin6);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
+ in_port_t port)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin.sin_family = AF_INET;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin);
+#endif
+ sockaddr->type.sin.sin_addr = *ina;
+ sockaddr->type.sin.sin_port = htons(port);
+ sockaddr->length = sizeof(sockaddr->type.sin);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_anyofpf(isc_sockaddr_t *sockaddr, int pf) {
+ switch (pf) {
+ case AF_INET:
+ isc_sockaddr_any(sockaddr);
+ break;
+ case AF_INET6:
+ isc_sockaddr_any6(sockaddr);
+ break;
+ default:
+ INSIST(0);
+ }
+}
+
+void
+isc_sockaddr_fromin6(isc_sockaddr_t *sockaddr, const struct in6_addr *ina6,
+ in_port_t port)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin6.sin6_family = AF_INET6;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
+#endif
+ sockaddr->type.sin6.sin6_addr = *ina6;
+ sockaddr->type.sin6.sin6_port = htons(port);
+ sockaddr->length = sizeof(sockaddr->type.sin6);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_v6fromin(isc_sockaddr_t *sockaddr, const struct in_addr *ina,
+ in_port_t port)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin6.sin6_family = AF_INET6;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
+#endif
+ sockaddr->type.sin6.sin6_addr.s6_addr[10] = 0xff;
+ sockaddr->type.sin6.sin6_addr.s6_addr[11] = 0xff;
+ memcpy(&sockaddr->type.sin6.sin6_addr.s6_addr[12], ina, 4);
+ sockaddr->type.sin6.sin6_port = htons(port);
+ sockaddr->length = sizeof(sockaddr->type.sin6);
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+int
+isc_sockaddr_pf(const isc_sockaddr_t *sockaddr) {
+
+ /*
+ * Get the protocol family of 'sockaddr'.
+ */
+
+#if (AF_INET == PF_INET && AF_INET6 == PF_INET6)
+ /*
+ * Assume that PF_xxx == AF_xxx for all AF and PF.
+ */
+ return (sockaddr->type.sa.sa_family);
+#else
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ return (PF_INET);
+ case AF_INET6:
+ return (PF_INET6);
+ default:
+ FATAL_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR,
+ ISC_MSG_UNKNOWNFAMILY,
+ "unknown address family: %d"),
+ (int)sockaddr->type.sa.sa_family);
+ }
+#endif
+}
+
+void
+isc_sockaddr_fromnetaddr(isc_sockaddr_t *sockaddr, const isc_netaddr_t *na,
+ in_port_t port)
+{
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->type.sin.sin_family = (short)na->family;
+ switch (na->family) {
+ case AF_INET:
+ sockaddr->length = sizeof(sockaddr->type.sin);
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin.sin_len = sizeof(sockaddr->type.sin);
+#endif
+ sockaddr->type.sin.sin_addr = na->type.in;
+ sockaddr->type.sin.sin_port = htons(port);
+ break;
+ case AF_INET6:
+ sockaddr->length = sizeof(sockaddr->type.sin6);
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sin6.sin6_len = sizeof(sockaddr->type.sin6);
+#endif
+ memcpy(&sockaddr->type.sin6.sin6_addr, &na->type.in6, 16);
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ sockaddr->type.sin6.sin6_scope_id = isc_netaddr_getzone(na);
+#endif
+ sockaddr->type.sin6.sin6_port = htons(port);
+ break;
+ default:
+ INSIST(0);
+ }
+ ISC_LINK_INIT(sockaddr, link);
+}
+
+void
+isc_sockaddr_setport(isc_sockaddr_t *sockaddr, in_port_t port) {
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ sockaddr->type.sin.sin_port = htons(port);
+ break;
+ case AF_INET6:
+ sockaddr->type.sin6.sin6_port = htons(port);
+ break;
+ default:
+ FATAL_ERROR(__FILE__, __LINE__,
+ "%s: %d",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR,
+ ISC_MSG_UNKNOWNFAMILY,
+ "unknown address family"),
+ (int)sockaddr->type.sa.sa_family);
+ }
+}
+
+in_port_t
+isc_sockaddr_getport(const isc_sockaddr_t *sockaddr) {
+ in_port_t port = 0;
+
+ switch (sockaddr->type.sa.sa_family) {
+ case AF_INET:
+ port = ntohs(sockaddr->type.sin.sin_port);
+ break;
+ case AF_INET6:
+ port = ntohs(sockaddr->type.sin6.sin6_port);
+ break;
+ default:
+ FATAL_ERROR(__FILE__, __LINE__,
+ "%s: %d",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_SOCKADDR,
+ ISC_MSG_UNKNOWNFAMILY,
+ "unknown address family"),
+ (int)sockaddr->type.sa.sa_family);
+ }
+
+ return (port);
+}
+
+isc_boolean_t
+isc_sockaddr_ismulticast(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET ||
+ sockaddr->type.sa.sa_family == AF_INET6) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_ismulticast(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
+isc_boolean_t
+isc_sockaddr_isexperimental(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_isexperimental(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
+isc_boolean_t
+isc_sockaddr_issitelocal(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET6) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_issitelocal(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
+isc_boolean_t
+isc_sockaddr_islinklocal(const isc_sockaddr_t *sockaddr) {
+ isc_netaddr_t netaddr;
+
+ if (sockaddr->type.sa.sa_family == AF_INET6) {
+ isc_netaddr_fromsockaddr(&netaddr, sockaddr);
+ return (isc_netaddr_islinklocal(&netaddr));
+ }
+ return (ISC_FALSE);
+}
+
+isc_result_t
+isc_sockaddr_frompath(isc_sockaddr_t *sockaddr, const char *path) {
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ if (strlen(path) >= sizeof(sockaddr->type.sunix.sun_path))
+ return (ISC_R_NOSPACE);
+ memset(sockaddr, 0, sizeof(*sockaddr));
+ sockaddr->length = sizeof(sockaddr->type.sunix);
+ sockaddr->type.sunix.sun_family = AF_UNIX;
+#ifdef ISC_PLATFORM_HAVESALEN
+ sockaddr->type.sunix.sun_len =
+ (unsigned char)sizeof(sockaddr->type.sunix);
+#endif
+ strcpy(sockaddr->type.sunix.sun_path, path);
+ return (ISC_R_SUCCESS);
+#else
+ UNUSED(sockaddr);
+ UNUSED(path);
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
diff --git a/contrib/ntp/libntp/lib/isc/task.c b/contrib/ntp/libntp/lib/isc/task.c
new file mode 100644
index 000000000000..5b899b350423
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/task.c
@@ -0,0 +1,1813 @@
+/*
+ * Copyright (C) 2004-2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file
+ * \author Principal Author: Bob Halley
+ */
+
+/*
+ * XXXRTH Need to document the states a task can be in, and the rules
+ * for changing states.
+ */
+
+#include <config.h>
+
+#include <isc/condition.h>
+#include <isc/event.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/platform.h>
+#include <isc/string.h>
+#include <isc/task.h>
+#include <isc/thread.h>
+#include <isc/util.h>
+#include <isc/xml.h>
+
+#ifdef OPENSSL_LEAKS
+#include <openssl/err.h>
+#endif
+
+/*%
+ * For BIND9 internal applications:
+ * when built with threads we use multiple worker threads shared by the whole
+ * application.
+ * when built without threads we share a single global task manager and use
+ * an integrated event loop for socket, timer, and other generic task events.
+ * For generic library:
+ * we don't use either of them: an application can have multiple task managers
+ * whether or not it's threaded, and if the application is threaded each thread
+ * is expected to have a separate manager; no "worker threads" are shared by
+ * the application threads.
+ */
+#ifdef BIND9
+#ifdef ISC_PLATFORM_USETHREADS
+#define USE_WORKER_THREADS
+#else
+#define USE_SHARED_MANAGER
+#endif /* ISC_PLATFORM_USETHREADS */
+#endif /* BIND9 */
+
+#include "task_p.h"
+
+#ifdef ISC_TASK_TRACE
+#define XTRACE(m) fprintf(stderr, "task %p thread %lu: %s\n", \
+ task, isc_thread_self(), (m))
+#define XTTRACE(t, m) fprintf(stderr, "task %p thread %lu: %s\n", \
+ (t), isc_thread_self(), (m))
+#define XTHREADTRACE(m) fprintf(stderr, "thread %lu: %s\n", \
+ isc_thread_self(), (m))
+#else
+#define XTRACE(m)
+#define XTTRACE(t, m)
+#define XTHREADTRACE(m)
+#endif
+
+/***
+ *** Types.
+ ***/
+
+typedef enum {
+ task_state_idle, task_state_ready, task_state_running,
+ task_state_done
+} task_state_t;
+
+#if defined(HAVE_LIBXML2) && defined(BIND9)
+static const char *statenames[] = {
+ "idle", "ready", "running", "done",
+};
+#endif
+
+#define TASK_MAGIC ISC_MAGIC('T', 'A', 'S', 'K')
+#define VALID_TASK(t) ISC_MAGIC_VALID(t, TASK_MAGIC)
+
+typedef struct isc__task isc__task_t;
+typedef struct isc__taskmgr isc__taskmgr_t;
+
+struct isc__task {
+ /* Not locked. */
+ isc_task_t common;
+ isc__taskmgr_t * manager;
+ isc_mutex_t lock;
+ /* Locked by task lock. */
+ task_state_t state;
+ unsigned int references;
+ isc_eventlist_t events;
+ isc_eventlist_t on_shutdown;
+ unsigned int quantum;
+ unsigned int flags;
+ isc_stdtime_t now;
+ char name[16];
+ void * tag;
+ /* Locked by task manager lock. */
+ LINK(isc__task_t) link;
+ LINK(isc__task_t) ready_link;
+ LINK(isc__task_t) ready_priority_link;
+};
+
+#define TASK_F_SHUTTINGDOWN 0x01
+#define TASK_F_PRIVILEGED 0x02
+
+#define TASK_SHUTTINGDOWN(t) (((t)->flags & TASK_F_SHUTTINGDOWN) \
+ != 0)
+
+#define TASK_MANAGER_MAGIC ISC_MAGIC('T', 'S', 'K', 'M')
+#define VALID_MANAGER(m) ISC_MAGIC_VALID(m, TASK_MANAGER_MAGIC)
+
+typedef ISC_LIST(isc__task_t) isc__tasklist_t;
+
+struct isc__taskmgr {
+ /* Not locked. */
+ isc_taskmgr_t common;
+ isc_mem_t * mctx;
+ isc_mutex_t lock;
+#ifdef ISC_PLATFORM_USETHREADS
+ unsigned int workers;
+ isc_thread_t * threads;
+#endif /* ISC_PLATFORM_USETHREADS */
+ /* Locked by task manager lock. */
+ unsigned int default_quantum;
+ LIST(isc__task_t) tasks;
+ isc__tasklist_t ready_tasks;
+ isc__tasklist_t ready_priority_tasks;
+ isc_taskmgrmode_t mode;
+#ifdef ISC_PLATFORM_USETHREADS
+ isc_condition_t work_available;
+ isc_condition_t exclusive_granted;
+ isc_condition_t paused;
+#endif /* ISC_PLATFORM_USETHREADS */
+ unsigned int tasks_running;
+ isc_boolean_t pause_requested;
+ isc_boolean_t exclusive_requested;
+ isc_boolean_t exiting;
+#ifdef USE_SHARED_MANAGER
+ unsigned int refs;
+#endif /* ISC_PLATFORM_USETHREADS */
+};
+
+#define DEFAULT_TASKMGR_QUANTUM 10
+#define DEFAULT_DEFAULT_QUANTUM 5
+#define FINISHED(m) ((m)->exiting && EMPTY((m)->tasks))
+
+#ifdef USE_SHARED_MANAGER
+static isc__taskmgr_t *taskmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
+
+/*%
+ * The following can be either static or public, depending on build environment.
+ */
+
+#ifdef BIND9
+#define ISC_TASKFUNC_SCOPE
+#else
+#define ISC_TASKFUNC_SCOPE static
+#endif
+
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum,
+ isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_attach(isc_task_t *source0, isc_task_t **targetp);
+ISC_TASKFUNC_SCOPE void
+isc__task_detach(isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_send(isc_task_t *task0, isc_event_t **eventp);
+ISC_TASKFUNC_SCOPE void
+isc__task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag);
+ISC_TASKFUNC_SCOPE isc_boolean_t
+isc__task_purgeevent(isc_task_t *task0, isc_event_t *event);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag,
+ isc_eventlist_t *events);
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action,
+ const void *arg);
+ISC_TASKFUNC_SCOPE void
+isc__task_shutdown(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void
+isc__task_destroy(isc_task_t **taskp);
+ISC_TASKFUNC_SCOPE void
+isc__task_setname(isc_task_t *task0, const char *name, void *tag);
+ISC_TASKFUNC_SCOPE const char *
+isc__task_getname(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void *
+isc__task_gettag(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void
+isc__task_getcurrenttime(isc_task_t *task0, isc_stdtime_t *t);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp);
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_destroy(isc_taskmgr_t **managerp);
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_beginexclusive(isc_task_t *task);
+ISC_TASKFUNC_SCOPE void
+isc__task_endexclusive(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void
+isc__task_setprivilege(isc_task_t *task0, isc_boolean_t priv);
+ISC_TASKFUNC_SCOPE isc_boolean_t
+isc__task_privilege(isc_task_t *task0);
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_setmode(isc_taskmgr_t *manager0, isc_taskmgrmode_t mode);
+ISC_TASKFUNC_SCOPE isc_taskmgrmode_t
+isc__taskmgr_mode(isc_taskmgr_t *manager0);
+
+static inline isc_boolean_t
+empty_readyq(isc__taskmgr_t *manager);
+
+static inline isc__task_t *
+pop_readyq(isc__taskmgr_t *manager);
+
+static inline void
+push_readyq(isc__taskmgr_t *manager, isc__task_t *task);
+
+static struct isc__taskmethods {
+ isc_taskmethods_t methods;
+
+ /*%
+ * The following are defined just for avoiding unused static functions.
+ */
+#ifndef BIND9
+ void *purgeevent, *unsendrange, *getname, *gettag, *getcurrenttime;
+#endif
+} taskmethods = {
+ {
+ isc__task_attach,
+ isc__task_detach,
+ isc__task_destroy,
+ isc__task_send,
+ isc__task_sendanddetach,
+ isc__task_unsend,
+ isc__task_onshutdown,
+ isc__task_shutdown,
+ isc__task_setname,
+ isc__task_purge,
+ isc__task_purgerange,
+ isc__task_beginexclusive,
+ isc__task_endexclusive,
+ isc__task_setprivilege,
+ isc__task_privilege
+ }
+#ifndef BIND9
+ ,
+ (void *)isc__task_purgeevent, (void *)isc__task_unsendrange,
+ (void *)isc__task_getname, (void *)isc__task_gettag,
+ (void *)isc__task_getcurrenttime
+#endif
+};
+
+static isc_taskmgrmethods_t taskmgrmethods = {
+ isc__taskmgr_destroy,
+ isc__taskmgr_setmode,
+ isc__taskmgr_mode,
+ isc__task_create
+};
+
+/***
+ *** Tasks.
+ ***/
+
+static void
+task_finished(isc__task_t *task) {
+ isc__taskmgr_t *manager = task->manager;
+
+ REQUIRE(EMPTY(task->events));
+ REQUIRE(EMPTY(task->on_shutdown));
+ REQUIRE(task->references == 0);
+ REQUIRE(task->state == task_state_done);
+
+ XTRACE("task_finished");
+
+ LOCK(&manager->lock);
+ UNLINK(manager->tasks, task, link);
+#ifdef USE_WORKER_THREADS
+ if (FINISHED(manager)) {
+ /*
+ * All tasks have completed and the
+ * task manager is exiting. Wake up
+ * any idle worker threads so they
+ * can exit.
+ */
+ BROADCAST(&manager->work_available);
+ }
+#endif /* USE_WORKER_THREADS */
+ UNLOCK(&manager->lock);
+
+ DESTROYLOCK(&task->lock);
+ task->common.impmagic = 0;
+ task->common.magic = 0;
+ isc_mem_put(manager->mctx, task, sizeof(*task));
+}
+
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_create(isc_taskmgr_t *manager0, unsigned int quantum,
+ isc_task_t **taskp)
+{
+ isc__taskmgr_t *manager = (void*)manager0;
+ isc__task_t *task;
+ isc_boolean_t exiting;
+ isc_result_t result;
+
+ REQUIRE(VALID_MANAGER(manager));
+ REQUIRE(taskp != NULL && *taskp == NULL);
+
+ task = isc_mem_get(manager->mctx, sizeof(*task));
+ if (task == NULL)
+ return (ISC_R_NOMEMORY);
+ XTRACE("isc_task_create");
+ result = isc_mutex_init(&task->lock);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_put(manager->mctx, task, sizeof(*task));
+ return (result);
+ }
+ LOCK(&manager->lock);
+ LOCK(&task->lock); /* helps coverity analysis noise ratio */
+ task->manager = manager;
+ task->state = task_state_idle;
+ task->references = 1;
+ INIT_LIST(task->events);
+ INIT_LIST(task->on_shutdown);
+ task->quantum = quantum;
+ task->flags = 0;
+ task->now = 0;
+ memset(task->name, 0, sizeof(task->name));
+ task->tag = NULL;
+ INIT_LINK(task, link);
+ INIT_LINK(task, ready_link);
+ INIT_LINK(task, ready_priority_link);
+ UNLOCK(&task->lock);
+ UNLOCK(&manager->lock);
+
+ exiting = ISC_FALSE;
+ LOCK(&manager->lock);
+ if (!manager->exiting) {
+ if (task->quantum == 0)
+ task->quantum = manager->default_quantum;
+ APPEND(manager->tasks, task, link);
+ } else
+ exiting = ISC_TRUE;
+ UNLOCK(&manager->lock);
+
+ if (exiting) {
+ DESTROYLOCK(&task->lock);
+ isc_mem_put(manager->mctx, task, sizeof(*task));
+ return (ISC_R_SHUTTINGDOWN);
+ }
+
+ task->common.methods = (isc_taskmethods_t *)&taskmethods;
+ task->common.magic = ISCAPI_TASK_MAGIC;
+ task->common.impmagic = TASK_MAGIC;
+ *taskp = (isc_task_t *)task;
+
+ return (ISC_R_SUCCESS);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_attach(isc_task_t *source0, isc_task_t **targetp) {
+ isc__task_t *source = (isc__task_t *)source0;
+
+ /*
+ * Attach *targetp to source.
+ */
+
+ REQUIRE(VALID_TASK(source));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ XTTRACE(source, "isc_task_attach");
+
+ LOCK(&source->lock);
+ source->references++;
+ UNLOCK(&source->lock);
+
+ *targetp = (isc_task_t *)source;
+}
+
+static inline isc_boolean_t
+task_shutdown(isc__task_t *task) {
+ isc_boolean_t was_idle = ISC_FALSE;
+ isc_event_t *event, *prev;
+
+ /*
+ * Caller must be holding the task's lock.
+ */
+
+ XTRACE("task_shutdown");
+
+ if (! TASK_SHUTTINGDOWN(task)) {
+ XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_SHUTTINGDOWN, "shutting down"));
+ task->flags |= TASK_F_SHUTTINGDOWN;
+ if (task->state == task_state_idle) {
+ INSIST(EMPTY(task->events));
+ task->state = task_state_ready;
+ was_idle = ISC_TRUE;
+ }
+ INSIST(task->state == task_state_ready ||
+ task->state == task_state_running);
+
+ /*
+ * Note that we post shutdown events LIFO.
+ */
+ for (event = TAIL(task->on_shutdown);
+ event != NULL;
+ event = prev) {
+ prev = PREV(event, ev_link);
+ DEQUEUE(task->on_shutdown, event, ev_link);
+ ENQUEUE(task->events, event, ev_link);
+ }
+ }
+
+ return (was_idle);
+}
+
+/*
+ * Moves a task onto the appropriate run queue.
+ *
+ * Caller must NOT hold manager lock.
+ */
+static inline void
+task_ready(isc__task_t *task) {
+ isc__taskmgr_t *manager = task->manager;
+#ifdef USE_WORKER_THREADS
+ isc_boolean_t has_privilege = isc__task_privilege((isc_task_t *) task);
+#endif /* USE_WORKER_THREADS */
+
+ REQUIRE(VALID_MANAGER(manager));
+ REQUIRE(task->state == task_state_ready);
+
+ XTRACE("task_ready");
+
+ LOCK(&manager->lock);
+ push_readyq(manager, task);
+#ifdef USE_WORKER_THREADS
+ if (manager->mode == isc_taskmgrmode_normal || has_privilege)
+ SIGNAL(&manager->work_available);
+#endif /* USE_WORKER_THREADS */
+ UNLOCK(&manager->lock);
+}
+
+static inline isc_boolean_t
+task_detach(isc__task_t *task) {
+
+ /*
+ * Caller must be holding the task lock.
+ */
+
+ REQUIRE(task->references > 0);
+
+ XTRACE("detach");
+
+ task->references--;
+ if (task->references == 0 && task->state == task_state_idle) {
+ INSIST(EMPTY(task->events));
+ /*
+ * There are no references to this task, and no
+ * pending events. We could try to optimize and
+ * either initiate shutdown or clean up the task,
+ * depending on its state, but it's easier to just
+ * make the task ready and allow run() or the event
+ * loop to deal with shutting down and termination.
+ */
+ task->state = task_state_ready;
+ return (ISC_TRUE);
+ }
+
+ return (ISC_FALSE);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_detach(isc_task_t **taskp) {
+ isc__task_t *task;
+ isc_boolean_t was_idle;
+
+ /*
+ * Detach *taskp from its task.
+ */
+
+ REQUIRE(taskp != NULL);
+ task = (isc__task_t *)*taskp;
+ REQUIRE(VALID_TASK(task));
+
+ XTRACE("isc_task_detach");
+
+ LOCK(&task->lock);
+ was_idle = task_detach(task);
+ UNLOCK(&task->lock);
+
+ if (was_idle)
+ task_ready(task);
+
+ *taskp = NULL;
+}
+
+static inline isc_boolean_t
+task_send(isc__task_t *task, isc_event_t **eventp) {
+ isc_boolean_t was_idle = ISC_FALSE;
+ isc_event_t *event;
+
+ /*
+ * Caller must be holding the task lock.
+ */
+
+ REQUIRE(eventp != NULL);
+ event = *eventp;
+ REQUIRE(event != NULL);
+ REQUIRE(event->ev_type > 0);
+ REQUIRE(task->state != task_state_done);
+
+ XTRACE("task_send");
+
+ if (task->state == task_state_idle) {
+ was_idle = ISC_TRUE;
+ INSIST(EMPTY(task->events));
+ task->state = task_state_ready;
+ }
+ INSIST(task->state == task_state_ready ||
+ task->state == task_state_running);
+ ENQUEUE(task->events, event, ev_link);
+ *eventp = NULL;
+
+ return (was_idle);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_send(isc_task_t *task0, isc_event_t **eventp) {
+ isc__task_t *task = (isc__task_t *)task0;
+ isc_boolean_t was_idle;
+
+ /*
+ * Send '*event' to 'task'.
+ */
+
+ REQUIRE(VALID_TASK(task));
+
+ XTRACE("isc_task_send");
+
+ /*
+ * We're trying hard to hold locks for as short a time as possible.
+ * We're also trying to hold as few locks as possible. This is why
+ * some processing is deferred until after the lock is released.
+ */
+ LOCK(&task->lock);
+ was_idle = task_send(task, eventp);
+ UNLOCK(&task->lock);
+
+ if (was_idle) {
+ /*
+ * We need to add this task to the ready queue.
+ *
+ * We've waited until now to do it because making a task
+ * ready requires locking the manager. If we tried to do
+ * this while holding the task lock, we could deadlock.
+ *
+ * We've changed the state to ready, so no one else will
+ * be trying to add this task to the ready queue. The
+ * only way to leave the ready state is by executing the
+ * task. It thus doesn't matter if events are added,
+ * removed, or a shutdown is started in the interval
+ * between the time we released the task lock, and the time
+ * we add the task to the ready queue.
+ */
+ task_ready(task);
+ }
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_sendanddetach(isc_task_t **taskp, isc_event_t **eventp) {
+ isc_boolean_t idle1, idle2;
+ isc__task_t *task;
+
+ /*
+ * Send '*event' to '*taskp' and then detach '*taskp' from its
+ * task.
+ */
+
+ REQUIRE(taskp != NULL);
+ task = (isc__task_t *)*taskp;
+ REQUIRE(VALID_TASK(task));
+
+ XTRACE("isc_task_sendanddetach");
+
+ LOCK(&task->lock);
+ idle1 = task_send(task, eventp);
+ idle2 = task_detach(task);
+ UNLOCK(&task->lock);
+
+ /*
+ * If idle1, then idle2 shouldn't be true as well since we're holding
+ * the task lock, and thus the task cannot switch from ready back to
+ * idle.
+ */
+ INSIST(!(idle1 && idle2));
+
+ if (idle1 || idle2)
+ task_ready(task);
+
+ *taskp = NULL;
+}
+
+#define PURGE_OK(event) (((event)->ev_attributes & ISC_EVENTATTR_NOPURGE) == 0)
+
+static unsigned int
+dequeue_events(isc__task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag,
+ isc_eventlist_t *events, isc_boolean_t purging)
+{
+ isc_event_t *event, *next_event;
+ unsigned int count = 0;
+
+ REQUIRE(VALID_TASK(task));
+ REQUIRE(last >= first);
+
+ XTRACE("dequeue_events");
+
+ /*
+ * Events matching 'sender', whose type is >= first and <= last, and
+ * whose tag is 'tag' will be dequeued. If 'purging', matching events
+ * which are marked as unpurgable will not be dequeued.
+ *
+ * sender == NULL means "any sender", and tag == NULL means "any tag".
+ */
+
+ LOCK(&task->lock);
+
+ for (event = HEAD(task->events); event != NULL; event = next_event) {
+ next_event = NEXT(event, ev_link);
+ if (event->ev_type >= first && event->ev_type <= last &&
+ (sender == NULL || event->ev_sender == sender) &&
+ (tag == NULL || event->ev_tag == tag) &&
+ (!purging || PURGE_OK(event))) {
+ DEQUEUE(task->events, event, ev_link);
+ ENQUEUE(*events, event, ev_link);
+ count++;
+ }
+ }
+
+ UNLOCK(&task->lock);
+
+ return (count);
+}
+
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purgerange(isc_task_t *task0, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag)
+{
+ isc__task_t *task = (isc__task_t *)task0;
+ unsigned int count;
+ isc_eventlist_t events;
+ isc_event_t *event, *next_event;
+
+ /*
+ * Purge events from a task's event queue.
+ */
+
+ XTRACE("isc_task_purgerange");
+
+ ISC_LIST_INIT(events);
+
+ count = dequeue_events(task, sender, first, last, tag, &events,
+ ISC_TRUE);
+
+ for (event = HEAD(events); event != NULL; event = next_event) {
+ next_event = NEXT(event, ev_link);
+ isc_event_free(&event);
+ }
+
+ /*
+ * Note that purging never changes the state of the task.
+ */
+
+ return (count);
+}
+
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_purge(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag)
+{
+ /*
+ * Purge events from a task's event queue.
+ */
+
+ XTRACE("isc_task_purge");
+
+ return (isc__task_purgerange(task, sender, type, type, tag));
+}
+
+ISC_TASKFUNC_SCOPE isc_boolean_t
+isc__task_purgeevent(isc_task_t *task0, isc_event_t *event) {
+ isc__task_t *task = (isc__task_t *)task0;
+ isc_event_t *curr_event, *next_event;
+
+ /*
+ * Purge 'event' from a task's event queue.
+ *
+ * XXXRTH: WARNING: This method may be removed before beta.
+ */
+
+ REQUIRE(VALID_TASK(task));
+
+ /*
+ * If 'event' is on the task's event queue, it will be purged,
+ * unless it is marked as unpurgeable. 'event' does not have to be
+ * on the task's event queue; in fact, it can even be an invalid
+ * pointer. Purging only occurs if the event is actually on the task's
+ * event queue.
+ *
+ * Purging never changes the state of the task.
+ */
+
+ LOCK(&task->lock);
+ for (curr_event = HEAD(task->events);
+ curr_event != NULL;
+ curr_event = next_event) {
+ next_event = NEXT(curr_event, ev_link);
+ if (curr_event == event && PURGE_OK(event)) {
+ DEQUEUE(task->events, curr_event, ev_link);
+ break;
+ }
+ }
+ UNLOCK(&task->lock);
+
+ if (curr_event == NULL)
+ return (ISC_FALSE);
+
+ isc_event_free(&curr_event);
+
+ return (ISC_TRUE);
+}
+
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsendrange(isc_task_t *task, void *sender, isc_eventtype_t first,
+ isc_eventtype_t last, void *tag,
+ isc_eventlist_t *events)
+{
+ /*
+ * Remove events from a task's event queue.
+ */
+
+ XTRACE("isc_task_unsendrange");
+
+ return (dequeue_events((isc__task_t *)task, sender, first,
+ last, tag, events, ISC_FALSE));
+}
+
+ISC_TASKFUNC_SCOPE unsigned int
+isc__task_unsend(isc_task_t *task, void *sender, isc_eventtype_t type,
+ void *tag, isc_eventlist_t *events)
+{
+ /*
+ * Remove events from a task's event queue.
+ */
+
+ XTRACE("isc_task_unsend");
+
+ return (dequeue_events((isc__task_t *)task, sender, type,
+ type, tag, events, ISC_FALSE));
+}
+
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_onshutdown(isc_task_t *task0, isc_taskaction_t action,
+ const void *arg)
+{
+ isc__task_t *task = (isc__task_t *)task0;
+ isc_boolean_t disallowed = ISC_FALSE;
+ isc_result_t result = ISC_R_SUCCESS;
+ isc_event_t *event;
+
+ /*
+ * Send a shutdown event with action 'action' and argument 'arg' when
+ * 'task' is shutdown.
+ */
+
+ REQUIRE(VALID_TASK(task));
+ REQUIRE(action != NULL);
+
+ event = isc_event_allocate(task->manager->mctx,
+ NULL,
+ ISC_TASKEVENT_SHUTDOWN,
+ action,
+ arg,
+ sizeof(*event));
+ if (event == NULL)
+ return (ISC_R_NOMEMORY);
+
+ LOCK(&task->lock);
+ if (TASK_SHUTTINGDOWN(task)) {
+ disallowed = ISC_TRUE;
+ result = ISC_R_SHUTTINGDOWN;
+ } else
+ ENQUEUE(task->on_shutdown, event, ev_link);
+ UNLOCK(&task->lock);
+
+ if (disallowed)
+ isc_mem_put(task->manager->mctx, event, sizeof(*event));
+
+ return (result);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_shutdown(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
+ isc_boolean_t was_idle;
+
+ /*
+ * Shutdown 'task'.
+ */
+
+ REQUIRE(VALID_TASK(task));
+
+ LOCK(&task->lock);
+ was_idle = task_shutdown(task);
+ UNLOCK(&task->lock);
+
+ if (was_idle)
+ task_ready(task);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_destroy(isc_task_t **taskp) {
+
+ /*
+ * Destroy '*taskp'.
+ */
+
+ REQUIRE(taskp != NULL);
+
+ isc_task_shutdown(*taskp);
+ isc_task_detach(taskp);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_setname(isc_task_t *task0, const char *name, void *tag) {
+ isc__task_t *task = (isc__task_t *)task0;
+
+ /*
+ * Name 'task'.
+ */
+
+ REQUIRE(VALID_TASK(task));
+
+ LOCK(&task->lock);
+ memset(task->name, 0, sizeof(task->name));
+ strncpy(task->name, name, sizeof(task->name) - 1);
+ task->tag = tag;
+ UNLOCK(&task->lock);
+}
+
+ISC_TASKFUNC_SCOPE const char *
+isc__task_getname(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
+
+ REQUIRE(VALID_TASK(task));
+
+ return (task->name);
+}
+
+ISC_TASKFUNC_SCOPE void *
+isc__task_gettag(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
+
+ REQUIRE(VALID_TASK(task));
+
+ return (task->tag);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_getcurrenttime(isc_task_t *task0, isc_stdtime_t *t) {
+ isc__task_t *task = (isc__task_t *)task0;
+
+ REQUIRE(VALID_TASK(task));
+ REQUIRE(t != NULL);
+
+ LOCK(&task->lock);
+ *t = task->now;
+ UNLOCK(&task->lock);
+}
+
+/***
+ *** Task Manager.
+ ***/
+
+/*
+ * Return ISC_TRUE if the current ready list for the manager, which is
+ * either ready_tasks or the ready_priority_tasks, depending on whether
+ * the manager is currently in normal or privileged execution mode.
+ *
+ * Caller must hold the task manager lock.
+ */
+static inline isc_boolean_t
+empty_readyq(isc__taskmgr_t *manager) {
+ isc__tasklist_t queue;
+
+ if (manager->mode == isc_taskmgrmode_normal)
+ queue = manager->ready_tasks;
+ else
+ queue = manager->ready_priority_tasks;
+
+ return (ISC_TF(EMPTY(queue)));
+}
+
+/*
+ * Dequeue and return a pointer to the first task on the current ready
+ * list for the manager.
+ * If the task is privileged, dequeue it from the other ready list
+ * as well.
+ *
+ * Caller must hold the task manager lock.
+ */
+static inline isc__task_t *
+pop_readyq(isc__taskmgr_t *manager) {
+ isc__task_t *task;
+
+ if (manager->mode == isc_taskmgrmode_normal)
+ task = HEAD(manager->ready_tasks);
+ else
+ task = HEAD(manager->ready_priority_tasks);
+
+ if (task != NULL) {
+ DEQUEUE(manager->ready_tasks, task, ready_link);
+ if (ISC_LINK_LINKED(task, ready_priority_link))
+ DEQUEUE(manager->ready_priority_tasks, task,
+ ready_priority_link);
+ }
+
+ return (task);
+}
+
+/*
+ * Push 'task' onto the ready_tasks queue. If 'task' has the privilege
+ * flag set, then also push it onto the ready_priority_tasks queue.
+ *
+ * Caller must hold the task manager lock.
+ */
+static inline void
+push_readyq(isc__taskmgr_t *manager, isc__task_t *task) {
+ ENQUEUE(manager->ready_tasks, task, ready_link);
+ if ((task->flags & TASK_F_PRIVILEGED) != 0)
+ ENQUEUE(manager->ready_priority_tasks, task,
+ ready_priority_link);
+}
+
+static void
+dispatch(isc__taskmgr_t *manager) {
+ isc__task_t *task;
+#ifndef USE_WORKER_THREADS
+ unsigned int total_dispatch_count = 0;
+ isc__tasklist_t new_ready_tasks;
+ isc__tasklist_t new_priority_tasks;
+#endif /* USE_WORKER_THREADS */
+
+ REQUIRE(VALID_MANAGER(manager));
+
+ /*
+ * Again we're trying to hold the lock for as short a time as possible
+ * and to do as little locking and unlocking as possible.
+ *
+ * In both while loops, the appropriate lock must be held before the
+ * while body starts. Code which acquired the lock at the top of
+ * the loop would be more readable, but would result in a lot of
+ * extra locking. Compare:
+ *
+ * Straightforward:
+ *
+ * LOCK();
+ * ...
+ * UNLOCK();
+ * while (expression) {
+ * LOCK();
+ * ...
+ * UNLOCK();
+ *
+ * Unlocked part here...
+ *
+ * LOCK();
+ * ...
+ * UNLOCK();
+ * }
+ *
+ * Note how if the loop continues we unlock and then immediately lock.
+ * For N iterations of the loop, this code does 2N+1 locks and 2N+1
+ * unlocks. Also note that the lock is not held when the while
+ * condition is tested, which may or may not be important, depending
+ * on the expression.
+ *
+ * As written:
+ *
+ * LOCK();
+ * while (expression) {
+ * ...
+ * UNLOCK();
+ *
+ * Unlocked part here...
+ *
+ * LOCK();
+ * ...
+ * }
+ * UNLOCK();
+ *
+ * For N iterations of the loop, this code does N+1 locks and N+1
+ * unlocks. The while expression is always protected by the lock.
+ */
+
+#ifndef USE_WORKER_THREADS
+ ISC_LIST_INIT(new_ready_tasks);
+ ISC_LIST_INIT(new_priority_tasks);
+#endif
+ LOCK(&manager->lock);
+
+ while (!FINISHED(manager)) {
+#ifdef USE_WORKER_THREADS
+ /*
+ * For reasons similar to those given in the comment in
+ * isc_task_send() above, it is safe for us to dequeue
+ * the task while only holding the manager lock, and then
+ * change the task to running state while only holding the
+ * task lock.
+ *
+ * If a pause has been requested, don't do any work
+ * until it's been released.
+ */
+ while ((empty_readyq(manager) || manager->pause_requested ||
+ manager->exclusive_requested) && !FINISHED(manager))
+ {
+ XTHREADTRACE(isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_WAIT, "wait"));
+ WAIT(&manager->work_available, &manager->lock);
+ XTHREADTRACE(isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_TASK,
+ ISC_MSG_AWAKE, "awake"));
+ }
+#else /* USE_WORKER_THREADS */
+ if (total_dispatch_count >= DEFAULT_TASKMGR_QUANTUM ||
+ empty_readyq(manager))
+ break;
+#endif /* USE_WORKER_THREADS */
+ XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_TASK,
+ ISC_MSG_WORKING, "working"));
+
+ task = pop_readyq(manager);
+ if (task != NULL) {
+ unsigned int dispatch_count = 0;
+ isc_boolean_t done = ISC_FALSE;
+ isc_boolean_t requeue = ISC_FALSE;
+ isc_boolean_t finished = ISC_FALSE;
+ isc_event_t *event;
+
+ INSIST(VALID_TASK(task));
+
+ /*
+ * Note we only unlock the manager lock if we actually
+ * have a task to do. We must reacquire the manager
+ * lock before exiting the 'if (task != NULL)' block.
+ */
+ manager->tasks_running++;
+ UNLOCK(&manager->lock);
+
+ LOCK(&task->lock);
+ INSIST(task->state == task_state_ready);
+ task->state = task_state_running;
+ XTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_RUNNING, "running"));
+ isc_stdtime_get(&task->now);
+ do {
+ if (!EMPTY(task->events)) {
+ event = HEAD(task->events);
+ DEQUEUE(task->events, event, ev_link);
+
+ /*
+ * Execute the event action.
+ */
+ XTRACE(isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_TASK,
+ ISC_MSG_EXECUTE,
+ "execute action"));
+ if (event->ev_action != NULL) {
+ UNLOCK(&task->lock);
+ (event->ev_action)(
+ (isc_task_t *)task,
+ event);
+ LOCK(&task->lock);
+ }
+ dispatch_count++;
+#ifndef USE_WORKER_THREADS
+ total_dispatch_count++;
+#endif /* USE_WORKER_THREADS */
+ }
+
+ if (task->references == 0 &&
+ EMPTY(task->events) &&
+ !TASK_SHUTTINGDOWN(task)) {
+ isc_boolean_t was_idle;
+
+ /*
+ * There are no references and no
+ * pending events for this task,
+ * which means it will not become
+ * runnable again via an external
+ * action (such as sending an event
+ * or detaching).
+ *
+ * We initiate shutdown to prevent
+ * it from becoming a zombie.
+ *
+ * We do this here instead of in
+ * the "if EMPTY(task->events)" block
+ * below because:
+ *
+ * If we post no shutdown events,
+ * we want the task to finish.
+ *
+ * If we did post shutdown events,
+ * will still want the task's
+ * quantum to be applied.
+ */
+ was_idle = task_shutdown(task);
+ INSIST(!was_idle);
+ }
+
+ if (EMPTY(task->events)) {
+ /*
+ * Nothing else to do for this task
+ * right now.
+ */
+ XTRACE(isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_TASK,
+ ISC_MSG_EMPTY,
+ "empty"));
+ if (task->references == 0 &&
+ TASK_SHUTTINGDOWN(task)) {
+ /*
+ * The task is done.
+ */
+ XTRACE(isc_msgcat_get(
+ isc_msgcat,
+ ISC_MSGSET_TASK,
+ ISC_MSG_DONE,
+ "done"));
+ finished = ISC_TRUE;
+ task->state = task_state_done;
+ } else
+ task->state = task_state_idle;
+ done = ISC_TRUE;
+ } else if (dispatch_count >= task->quantum) {
+ /*
+ * Our quantum has expired, but
+ * there is more work to be done.
+ * We'll requeue it to the ready
+ * queue later.
+ *
+ * We don't check quantum until
+ * dispatching at least one event,
+ * so the minimum quantum is one.
+ */
+ XTRACE(isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_TASK,
+ ISC_MSG_QUANTUM,
+ "quantum"));
+ task->state = task_state_ready;
+ requeue = ISC_TRUE;
+ done = ISC_TRUE;
+ }
+ } while (!done);
+ UNLOCK(&task->lock);
+
+ if (finished)
+ task_finished(task);
+
+ LOCK(&manager->lock);
+ manager->tasks_running--;
+#ifdef USE_WORKER_THREADS
+ if (manager->exclusive_requested &&
+ manager->tasks_running == 1) {
+ SIGNAL(&manager->exclusive_granted);
+ } else if (manager->pause_requested &&
+ manager->tasks_running == 0) {
+ SIGNAL(&manager->paused);
+ }
+#endif /* USE_WORKER_THREADS */
+ if (requeue) {
+ /*
+ * We know we're awake, so we don't have
+ * to wakeup any sleeping threads if the
+ * ready queue is empty before we requeue.
+ *
+ * A possible optimization if the queue is
+ * empty is to 'goto' the 'if (task != NULL)'
+ * block, avoiding the ENQUEUE of the task
+ * and the subsequent immediate DEQUEUE
+ * (since it is the only executable task).
+ * We don't do this because then we'd be
+ * skipping the exit_requested check. The
+ * cost of ENQUEUE is low anyway, especially
+ * when you consider that we'd have to do
+ * an extra EMPTY check to see if we could
+ * do the optimization. If the ready queue
+ * were usually nonempty, the 'optimization'
+ * might even hurt rather than help.
+ */
+#ifdef USE_WORKER_THREADS
+ push_readyq(manager, task);
+#else
+ ENQUEUE(new_ready_tasks, task, ready_link);
+ if ((task->flags & TASK_F_PRIVILEGED) != 0)
+ ENQUEUE(new_priority_tasks, task,
+ ready_priority_link);
+#endif
+ }
+ }
+
+#ifdef USE_WORKER_THREADS
+ /*
+ * If we are in privileged execution mode and there are no
+ * tasks remaining on the current ready queue, then
+ * we're stuck. Automatically drop privileges at that
+ * point and continue with the regular ready queue.
+ */
+ if (manager->tasks_running == 0 && empty_readyq(manager)) {
+ manager->mode = isc_taskmgrmode_normal;
+ if (!empty_readyq(manager))
+ BROADCAST(&manager->work_available);
+ }
+#endif
+ }
+
+#ifndef USE_WORKER_THREADS
+ ISC_LIST_APPENDLIST(manager->ready_tasks, new_ready_tasks, ready_link);
+ ISC_LIST_APPENDLIST(manager->ready_priority_tasks, new_priority_tasks,
+ ready_priority_link);
+ if (empty_readyq(manager))
+ manager->mode = isc_taskmgrmode_normal;
+#endif
+
+ UNLOCK(&manager->lock);
+}
+
+#ifdef USE_WORKER_THREADS
+static isc_threadresult_t
+#ifdef _WIN32
+WINAPI
+#endif
+run(void *uap) {
+ isc__taskmgr_t *manager = uap;
+
+ XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_STARTING, "starting"));
+
+ dispatch(manager);
+
+ XTHREADTRACE(isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_EXITING, "exiting"));
+
+#ifdef OPENSSL_LEAKS
+ ERR_remove_state(0);
+#endif
+
+ return ((isc_threadresult_t)0);
+}
+#endif /* USE_WORKER_THREADS */
+
+static void
+manager_free(isc__taskmgr_t *manager) {
+ isc_mem_t *mctx;
+
+ LOCK(&manager->lock);
+#ifdef USE_WORKER_THREADS
+ (void)isc_condition_destroy(&manager->exclusive_granted);
+ (void)isc_condition_destroy(&manager->work_available);
+ (void)isc_condition_destroy(&manager->paused);
+ isc_mem_free(manager->mctx, manager->threads);
+#endif /* USE_WORKER_THREADS */
+ manager->common.impmagic = 0;
+ manager->common.magic = 0;
+ mctx = manager->mctx;
+ UNLOCK(&manager->lock);
+ DESTROYLOCK(&manager->lock);
+ isc_mem_put(mctx, manager, sizeof(*manager));
+ isc_mem_detach(&mctx);
+
+#ifdef USE_SHARED_MANAGER
+ taskmgr = NULL;
+#endif /* USE_SHARED_MANAGER */
+}
+
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__taskmgr_create(isc_mem_t *mctx, unsigned int workers,
+ unsigned int default_quantum, isc_taskmgr_t **managerp)
+{
+ isc_result_t result;
+ unsigned int i, started = 0;
+ isc__taskmgr_t *manager;
+
+ /*
+ * Create a new task manager.
+ */
+
+ REQUIRE(workers > 0);
+ REQUIRE(managerp != NULL && *managerp == NULL);
+
+#ifndef USE_WORKER_THREADS
+ UNUSED(i);
+ UNUSED(started);
+#endif
+
+#ifdef USE_SHARED_MANAGER
+ if (taskmgr != NULL) {
+ if (taskmgr->refs == 0)
+ return (ISC_R_SHUTTINGDOWN);
+ taskmgr->refs++;
+ *managerp = (isc_taskmgr_t *)taskmgr;
+ return (ISC_R_SUCCESS);
+ }
+#endif /* USE_SHARED_MANAGER */
+
+ manager = isc_mem_get(mctx, sizeof(*manager));
+ if (manager == NULL)
+ return (ISC_R_NOMEMORY);
+ manager->common.methods = &taskmgrmethods;
+ manager->common.impmagic = TASK_MANAGER_MAGIC;
+ manager->common.magic = ISCAPI_TASKMGR_MAGIC;
+ manager->mode = isc_taskmgrmode_normal;
+ manager->mctx = NULL;
+ result = isc_mutex_init(&manager->lock);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_mgr;
+ LOCK(&manager->lock);
+
+#ifdef USE_WORKER_THREADS
+ manager->workers = 0;
+ manager->threads = isc_mem_allocate(mctx,
+ workers * sizeof(isc_thread_t));
+ if (manager->threads == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto cleanup_lock;
+ }
+ if (isc_condition_init(&manager->work_available) != ISC_R_SUCCESS) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_condition_init() %s",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+ result = ISC_R_UNEXPECTED;
+ goto cleanup_threads;
+ }
+ if (isc_condition_init(&manager->exclusive_granted) != ISC_R_SUCCESS) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_condition_init() %s",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+ result = ISC_R_UNEXPECTED;
+ goto cleanup_workavailable;
+ }
+ if (isc_condition_init(&manager->paused) != ISC_R_SUCCESS) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "isc_condition_init() %s",
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+ result = ISC_R_UNEXPECTED;
+ goto cleanup_exclusivegranted;
+ }
+#endif /* USE_WORKER_THREADS */
+ if (default_quantum == 0)
+ default_quantum = DEFAULT_DEFAULT_QUANTUM;
+ manager->default_quantum = default_quantum;
+ INIT_LIST(manager->tasks);
+ INIT_LIST(manager->ready_tasks);
+ INIT_LIST(manager->ready_priority_tasks);
+ manager->tasks_running = 0;
+ manager->exclusive_requested = ISC_FALSE;
+ manager->pause_requested = ISC_FALSE;
+ manager->exiting = ISC_FALSE;
+
+ isc_mem_attach(mctx, &manager->mctx);
+
+#ifdef USE_WORKER_THREADS
+ /*
+ * Start workers.
+ */
+ for (i = 0; i < workers; i++) {
+ if (isc_thread_create(run, manager,
+ &manager->threads[manager->workers]) ==
+ ISC_R_SUCCESS) {
+ manager->workers++;
+ started++;
+ }
+ }
+ UNLOCK(&manager->lock);
+
+ if (started == 0) {
+ manager_free(manager);
+ return (ISC_R_NOTHREADS);
+ }
+ isc_thread_setconcurrency(workers);
+#endif /* USE_WORKER_THREADS */
+#ifdef USE_SHARED_MANAGER
+ manager->refs = 1;
+ UNLOCK(&manager->lock);
+ taskmgr = manager;
+#endif /* USE_SHARED_MANAGER */
+
+ *managerp = (isc_taskmgr_t *)manager;
+
+ return (ISC_R_SUCCESS);
+
+#ifdef USE_WORKER_THREADS
+ cleanup_exclusivegranted:
+ (void)isc_condition_destroy(&manager->exclusive_granted);
+ cleanup_workavailable:
+ (void)isc_condition_destroy(&manager->work_available);
+ cleanup_threads:
+ isc_mem_free(mctx, manager->threads);
+ cleanup_lock:
+ UNLOCK(&manager->lock);
+ DESTROYLOCK(&manager->lock);
+#endif
+ cleanup_mgr:
+ isc_mem_put(mctx, manager, sizeof(*manager));
+ return (result);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_destroy(isc_taskmgr_t **managerp) {
+ isc__taskmgr_t *manager;
+ isc__task_t *task;
+ unsigned int i;
+
+ /*
+ * Destroy '*managerp'.
+ */
+
+ REQUIRE(managerp != NULL);
+ manager = (void*)(*managerp);
+ REQUIRE(VALID_MANAGER(manager));
+
+#ifndef USE_WORKER_THREADS
+ UNUSED(i);
+#endif /* USE_WORKER_THREADS */
+
+#ifdef USE_SHARED_MANAGER
+ manager->refs--;
+ if (manager->refs > 0) {
+ *managerp = NULL;
+ return;
+ }
+#endif
+
+ XTHREADTRACE("isc_taskmgr_destroy");
+ /*
+ * Only one non-worker thread may ever call this routine.
+ * If a worker thread wants to initiate shutdown of the
+ * task manager, it should ask some non-worker thread to call
+ * isc_taskmgr_destroy(), e.g. by signalling a condition variable
+ * that the startup thread is sleeping on.
+ */
+
+ /*
+ * Unlike elsewhere, we're going to hold this lock a long time.
+ * We need to do so, because otherwise the list of tasks could
+ * change while we were traversing it.
+ *
+ * This is also the only function where we will hold both the
+ * task manager lock and a task lock at the same time.
+ */
+
+ LOCK(&manager->lock);
+
+ /*
+ * Make sure we only get called once.
+ */
+ INSIST(!manager->exiting);
+ manager->exiting = ISC_TRUE;
+
+ /*
+ * If privileged mode was on, turn it off.
+ */
+ manager->mode = isc_taskmgrmode_normal;
+
+ /*
+ * Post shutdown event(s) to every task (if they haven't already been
+ * posted).
+ */
+ for (task = HEAD(manager->tasks);
+ task != NULL;
+ task = NEXT(task, link)) {
+ LOCK(&task->lock);
+ if (task_shutdown(task))
+ push_readyq(manager, task);
+ UNLOCK(&task->lock);
+ }
+#ifdef USE_WORKER_THREADS
+ /*
+ * Wake up any sleeping workers. This ensures we get work done if
+ * there's work left to do, and if there are already no tasks left
+ * it will cause the workers to see manager->exiting.
+ */
+ BROADCAST(&manager->work_available);
+ UNLOCK(&manager->lock);
+
+ /*
+ * Wait for all the worker threads to exit.
+ */
+ for (i = 0; i < manager->workers; i++)
+ (void)isc_thread_join(manager->threads[i], NULL);
+#else /* USE_WORKER_THREADS */
+ /*
+ * Dispatch the shutdown events.
+ */
+ UNLOCK(&manager->lock);
+ while (isc__taskmgr_ready((isc_taskmgr_t *)manager))
+ (void)isc__taskmgr_dispatch((isc_taskmgr_t *)manager);
+#ifdef BIND9
+ if (!ISC_LIST_EMPTY(manager->tasks))
+ isc_mem_printallactive(stderr);
+#endif
+ INSIST(ISC_LIST_EMPTY(manager->tasks));
+#ifdef USE_SHARED_MANAGER
+ taskmgr = NULL;
+#endif
+#endif /* USE_WORKER_THREADS */
+
+ manager_free(manager);
+
+ *managerp = NULL;
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_setmode(isc_taskmgr_t *manager0, isc_taskmgrmode_t mode) {
+ isc__taskmgr_t *manager = (void*)manager0;
+
+ LOCK(&manager->lock);
+ manager->mode = mode;
+ UNLOCK(&manager->lock);
+}
+
+ISC_TASKFUNC_SCOPE isc_taskmgrmode_t
+isc__taskmgr_mode(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (void*)manager0;
+ isc_taskmgrmode_t mode;
+ LOCK(&manager->lock);
+ mode = manager->mode;
+ UNLOCK(&manager->lock);
+ return (mode);
+}
+
+#ifndef USE_WORKER_THREADS
+isc_boolean_t
+isc__taskmgr_ready(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (void*)manager0;
+ isc_boolean_t is_ready;
+
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = taskmgr;
+#endif
+ if (manager == NULL)
+ return (ISC_FALSE);
+
+ LOCK(&manager->lock);
+ is_ready = !empty_readyq(manager);
+ UNLOCK(&manager->lock);
+
+ return (is_ready);
+}
+
+isc_result_t
+isc__taskmgr_dispatch(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (void*)manager0;
+
+#ifdef USE_SHARED_MANAGER
+ if (manager == NULL)
+ manager = taskmgr;
+#endif
+ if (manager == NULL)
+ return (ISC_R_NOTFOUND);
+
+ dispatch(manager);
+
+ return (ISC_R_SUCCESS);
+}
+
+#else
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_pause(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (void*)manager0;
+ LOCK(&manager->lock);
+ while (manager->tasks_running > 0) {
+ WAIT(&manager->paused, &manager->lock);
+ }
+ manager->pause_requested = ISC_TRUE;
+ UNLOCK(&manager->lock);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__taskmgr_resume(isc_taskmgr_t *manager0) {
+ isc__taskmgr_t *manager = (void*)manager0;
+
+ LOCK(&manager->lock);
+ if (manager->pause_requested) {
+ manager->pause_requested = ISC_FALSE;
+ BROADCAST(&manager->work_available);
+ }
+ UNLOCK(&manager->lock);
+}
+#endif /* USE_WORKER_THREADS */
+
+ISC_TASKFUNC_SCOPE isc_result_t
+isc__task_beginexclusive(isc_task_t *task0) {
+#ifdef USE_WORKER_THREADS
+ isc__task_t *task = (isc__task_t *)task0;
+ isc__taskmgr_t *manager = task->manager;
+ REQUIRE(task->state == task_state_running);
+ LOCK(&manager->lock);
+ if (manager->exclusive_requested) {
+ UNLOCK(&manager->lock);
+ return (ISC_R_LOCKBUSY);
+ }
+ manager->exclusive_requested = ISC_TRUE;
+ while (manager->tasks_running > 1) {
+ WAIT(&manager->exclusive_granted, &manager->lock);
+ }
+ UNLOCK(&manager->lock);
+#else
+ UNUSED(task0);
+#endif
+ return (ISC_R_SUCCESS);
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_endexclusive(isc_task_t *task0) {
+#ifdef USE_WORKER_THREADS
+ isc__task_t *task = (isc__task_t *)task0;
+ isc__taskmgr_t *manager = task->manager;
+
+ REQUIRE(task->state == task_state_running);
+ LOCK(&manager->lock);
+ REQUIRE(manager->exclusive_requested);
+ manager->exclusive_requested = ISC_FALSE;
+ BROADCAST(&manager->work_available);
+ UNLOCK(&manager->lock);
+#else
+ UNUSED(task0);
+#endif
+}
+
+ISC_TASKFUNC_SCOPE void
+isc__task_setprivilege(isc_task_t *task0, isc_boolean_t priv) {
+ isc__task_t *task = (isc__task_t *)task0;
+ isc__taskmgr_t *manager = task->manager;
+ isc_boolean_t oldpriv;
+
+ LOCK(&task->lock);
+ oldpriv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0);
+ if (priv)
+ task->flags |= TASK_F_PRIVILEGED;
+ else
+ task->flags &= ~TASK_F_PRIVILEGED;
+ UNLOCK(&task->lock);
+
+ if (priv == oldpriv)
+ return;
+
+ LOCK(&manager->lock);
+ if (priv && ISC_LINK_LINKED(task, ready_link))
+ ENQUEUE(manager->ready_priority_tasks, task,
+ ready_priority_link);
+ else if (!priv && ISC_LINK_LINKED(task, ready_priority_link))
+ DEQUEUE(manager->ready_priority_tasks, task,
+ ready_priority_link);
+ UNLOCK(&manager->lock);
+}
+
+ISC_TASKFUNC_SCOPE isc_boolean_t
+isc__task_privilege(isc_task_t *task0) {
+ isc__task_t *task = (isc__task_t *)task0;
+ isc_boolean_t priv;
+
+ LOCK(&task->lock);
+ priv = ISC_TF((task->flags & TASK_F_PRIVILEGED) != 0);
+ UNLOCK(&task->lock);
+ return (priv);
+}
+
+#ifdef USE_SOCKETIMPREGISTER
+isc_result_t
+isc__task_register() {
+ return (isc_task_register(isc__taskmgr_create));
+}
+#endif
+
+isc_boolean_t
+isc_task_exiting(isc_task_t *t) {
+ isc__task_t *task = (isc__task_t *)t;
+
+ REQUIRE(VALID_TASK(task));
+ return (TASK_SHUTTINGDOWN(task));
+}
+
+
+#if defined(HAVE_LIBXML2) && defined(BIND9)
+void
+isc_taskmgr_renderxml(isc_taskmgr_t *mgr0, xmlTextWriterPtr writer) {
+ isc__taskmgr_t *mgr = (isc__taskmgr_t *)mgr0;
+ isc__task_t *task;
+
+ LOCK(&mgr->lock);
+
+ /*
+ * Write out the thread-model, and some details about each depending
+ * on which type is enabled.
+ */
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "thread-model");
+#ifdef ISC_PLATFORM_USETHREADS
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "type");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR "threaded");
+ xmlTextWriterEndElement(writer); /* type */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "worker-threads");
+ xmlTextWriterWriteFormatString(writer, "%d", mgr->workers);
+ xmlTextWriterEndElement(writer); /* worker-threads */
+#else /* ISC_PLATFORM_USETHREADS */
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "type");
+ xmlTextWriterWriteString(writer, ISC_XMLCHAR "non-threaded");
+ xmlTextWriterEndElement(writer); /* type */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
+ xmlTextWriterWriteFormatString(writer, "%d", mgr->refs);
+ xmlTextWriterEndElement(writer); /* references */
+#endif /* ISC_PLATFORM_USETHREADS */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "default-quantum");
+ xmlTextWriterWriteFormatString(writer, "%d", mgr->default_quantum);
+ xmlTextWriterEndElement(writer); /* default-quantum */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks-running");
+ xmlTextWriterWriteFormatString(writer, "%d", mgr->tasks_running);
+ xmlTextWriterEndElement(writer); /* tasks-running */
+
+ xmlTextWriterEndElement(writer); /* thread-model */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "tasks");
+ task = ISC_LIST_HEAD(mgr->tasks);
+ while (task != NULL) {
+ LOCK(&task->lock);
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "task");
+
+ if (task->name[0] != 0) {
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
+ xmlTextWriterWriteFormatString(writer, "%s",
+ task->name);
+ xmlTextWriterEndElement(writer); /* name */
+ }
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
+ xmlTextWriterWriteFormatString(writer, "%d", task->references);
+ xmlTextWriterEndElement(writer); /* references */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "id");
+ xmlTextWriterWriteFormatString(writer, "%p", task);
+ xmlTextWriterEndElement(writer); /* id */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "state");
+ xmlTextWriterWriteFormatString(writer, "%s",
+ statenames[task->state]);
+ xmlTextWriterEndElement(writer); /* state */
+
+ xmlTextWriterStartElement(writer, ISC_XMLCHAR "quantum");
+ xmlTextWriterWriteFormatString(writer, "%d", task->quantum);
+ xmlTextWriterEndElement(writer); /* quantum */
+
+ xmlTextWriterEndElement(writer);
+
+ UNLOCK(&task->lock);
+ task = ISC_LIST_NEXT(task, link);
+ }
+ xmlTextWriterEndElement(writer); /* tasks */
+
+ UNLOCK(&mgr->lock);
+}
+#endif /* HAVE_LIBXML2 && BIND9 */
diff --git a/contrib/ntp/libntp/lib/isc/task_p.h b/contrib/ntp/libntp/lib/isc/task_p.h
new file mode 100644
index 000000000000..8c1e4c52fa4c
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/task_p.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_TASK_P_H
+#define ISC_TASK_P_H
+
+/*! \file */
+
+#if defined(BIND9) && defined(ISC_PLATFORM_USETHREADS)
+void
+isc__taskmgr_pause(isc_taskmgr_t *taskmgr);
+
+void
+isc__taskmgr_resume(isc_taskmgr_t *taskmgr);
+#else
+isc_boolean_t
+isc__taskmgr_ready(isc_taskmgr_t *taskmgr);
+
+isc_result_t
+isc__taskmgr_dispatch(isc_taskmgr_t *taskmgr);
+#endif /* !BIND9 || !ISC_PLATFORM_USETHREADS */
+
+#endif /* ISC_TASK_P_H */
diff --git a/contrib/ntp/libntp/lib/isc/tsmemcmp.c b/contrib/ntp/libntp/lib/isc/tsmemcmp.c
new file mode 100644
index 000000000000..e6af42eafc0f
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/tsmemcmp.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004-2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+#include <limits.h>
+#include <isc/string.h>
+
+/* Making a portable memcmp that has no internal branches and loops always
+ * once for every byte without early-out shortcut has a few challenges.
+ *
+ * Inspired by 'timingsafe_memcmp()' from the BSD system and
+ * https://github.com/libressl-portable/openbsd/blob/master/src/lib/libc/string/timingsafe_memcmp.c
+ *
+ * Sadly, that one is not portable C: It makes assumptions on the representation
+ * of negative integers and assumes sign-preserving right-shift of negative
+ * signed values. This is a rewrite from scratch that should not suffer from
+ * such issues.
+ *
+ * 2015-12-12, J. Perlinger (perlinger-at-ntp-dot-org)
+ */
+int
+isc_tsmemcmp(const void *p1, const void *p2, size_t nb) {
+ const unsigned char *ucp1 = p1;
+ const unsigned char *ucp2 = p2;
+ unsigned int isLT = 0u;
+ unsigned int isGT = 0u;
+ volatile unsigned int mask = (1u << CHAR_BIT);
+
+ for (/*NOP*/; 0 != nb; --nb, ++ucp1, ++ucp2) {
+ isLT |= mask &
+ ((unsigned int)*ucp1 - (unsigned int)*ucp2);
+ isGT |= mask &
+ ((unsigned int)*ucp2 - (unsigned int)*ucp1);
+ mask &= ~(isLT | isGT);
+ }
+ return (int)(isGT >> CHAR_BIT) - (int)(isLT >> CHAR_BIT);
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/dir.c b/contrib/ntp/libntp/lib/isc/unix/dir.c
new file mode 100644
index 000000000000..613ee5630d65
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/dir.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file
+ * \author Principal Authors: DCL */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <unistd.h>
+
+#include <isc/dir.h>
+#include <isc/magic.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#include "errno2result.h"
+#include "ntp_stdlib.h" /* NTP change for strlcpy, strlcat */
+
+#define ISC_DIR_MAGIC ISC_MAGIC('D', 'I', 'R', '*')
+#define VALID_DIR(dir) ISC_MAGIC_VALID(dir, ISC_DIR_MAGIC)
+
+void
+isc_dir_init(isc_dir_t *dir) {
+ REQUIRE(dir != NULL);
+
+ dir->entry.name[0] = '\0';
+ dir->entry.length = 0;
+
+ dir->handle = NULL;
+
+ dir->magic = ISC_DIR_MAGIC;
+}
+
+/*!
+ * \brief Allocate workspace and open directory stream. If either one fails,
+ * NULL will be returned.
+ */
+isc_result_t
+isc_dir_open(isc_dir_t *dir, const char *dirname) {
+ char *p;
+ size_t octets;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(VALID_DIR(dir));
+ REQUIRE(dirname != NULL);
+
+ /*
+ * Copy directory name. Need to have enough space for the name,
+ * a possible path separator, the wildcard, and the final NUL.
+ */
+ octets = strlen(dirname) + 1;
+ if (octets + 2 > sizeof(dir->dirname))
+ /* XXXDCL ? */
+ return (ISC_R_NOSPACE);
+ strlcpy(dir->dirname, dirname, octets);
+
+ /*
+ * Append path separator, if needed, and "*".
+ */
+ p = dir->dirname + strlen(dir->dirname);
+ if (dir->dirname < p && *(p - 1) != '/')
+ *p++ = '/';
+ *p++ = '*';
+ *p = '\0';
+
+ /*
+ * Open stream.
+ */
+ dir->handle = opendir(dirname);
+
+ if (dir->handle == NULL)
+ return isc__errno2result(errno);
+
+ return (result);
+}
+
+/*!
+ * \brief Return previously retrieved file or get next one.
+
+ * Unix's dirent has
+ * separate open and read functions, but the Win32 and DOS interfaces open
+ * the dir stream and reads the first file in one operation.
+ */
+isc_result_t
+isc_dir_read(isc_dir_t *dir) {
+ struct dirent *entry;
+ size_t octets;
+
+ REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
+
+ /*
+ * Fetch next file in directory.
+ */
+ entry = readdir(dir->handle);
+
+ if (entry == NULL)
+ return (ISC_R_NOMORE);
+
+ /*
+ * Make sure that the space for the name is long enough.
+ */
+ octets = strlen(entry->d_name) + 1;
+ if (sizeof(dir->entry.name) < octets)
+ return (ISC_R_UNEXPECTED);
+
+ strlcpy(dir->entry.name, entry->d_name, octets);
+
+ /*
+ * Some dirents have d_namlen, but it is not portable.
+ */
+ dir->entry.length = strlen(entry->d_name);
+
+ return (ISC_R_SUCCESS);
+}
+
+/*!
+ * \brief Close directory stream.
+ */
+void
+isc_dir_close(isc_dir_t *dir) {
+ REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
+
+ (void)closedir(dir->handle);
+ dir->handle = NULL;
+}
+
+/*!
+ * \brief Reposition directory stream at start.
+ */
+isc_result_t
+isc_dir_reset(isc_dir_t *dir) {
+ REQUIRE(VALID_DIR(dir) && dir->handle != NULL);
+
+ rewinddir(dir->handle);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_dir_chdir(const char *dirname) {
+ /*!
+ * \brief Change the current directory to 'dirname'.
+ */
+
+ REQUIRE(dirname != NULL);
+
+ if (chdir(dirname) < 0)
+ return (isc__errno2result(errno));
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_dir_chroot(const char *dirname) {
+
+ REQUIRE(dirname != NULL);
+
+#ifdef HAVE_CHROOT
+ if (chroot(dirname) < 0 || chdir("/") < 0)
+ return (isc__errno2result(errno));
+
+ return (ISC_R_SUCCESS);
+#else
+ return (ISC_R_NOTIMPLEMENTED);
+#endif
+}
+
+isc_result_t
+isc_dir_createunique(char *templet) {
+ isc_result_t result;
+ char *x;
+ char *p;
+ int i;
+ int pid;
+
+ REQUIRE(templet != NULL);
+
+ /*!
+ * \brief mkdtemp is not portable, so this emulates it.
+ */
+
+ pid = getpid();
+
+ /*
+ * Replace trailing Xs with the process-id, zero-filled.
+ */
+ for (x = templet + strlen(templet) - 1; *x == 'X' && x >= templet;
+ x--, pid /= 10)
+ *x = pid % 10 + '0';
+
+ x++; /* Set x to start of ex-Xs. */
+
+ do {
+ i = mkdir(templet, 0700);
+ if (i == 0 || errno != EEXIST)
+ break;
+
+ /*
+ * The BSD algorithm.
+ */
+ p = x;
+ while (*p != '\0') {
+ if (isdigit(*p & 0xff))
+ *p = 'a';
+ else if (*p != 'z')
+ ++*p;
+ else {
+ /*
+ * Reset character and move to next.
+ */
+ *p++ = 'a';
+ continue;
+ }
+
+ break;
+ }
+
+ if (*p == '\0') {
+ /*
+ * Tried all combinations. errno should already
+ * be EEXIST, but ensure it is anyway for
+ * isc__errno2result().
+ */
+ errno = EEXIST;
+ break;
+ }
+ } while (1);
+
+ if (i == -1)
+ result = isc__errno2result(errno);
+ else
+ result = ISC_R_SUCCESS;
+
+ return (result);
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/errno2result.c b/contrib/ntp/libntp/lib/isc/unix/errno2result.c
new file mode 100644
index 000000000000..f20aa295ca9c
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/errno2result.c
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isc/result.h>
+#include <isc/strerror.h>
+#include <isc/util.h>
+
+#include "errno2result.h"
+
+/*%
+ * Convert a POSIX errno value into an isc_result_t. The
+ * list of supported errno values is not complete; new users
+ * of this function should add any expected errors that are
+ * not already there.
+ */
+isc_result_t
+isc___errno2result(int posixerrno, const char *file, unsigned int line) {
+ char strbuf[ISC_STRERRORSIZE];
+
+ switch (posixerrno) {
+ case ENOTDIR:
+ case ELOOP:
+ case EINVAL: /* XXX sometimes this is not for files */
+ case ENAMETOOLONG:
+ case EBADF:
+ return (ISC_R_INVALIDFILE);
+ case ENOENT:
+ return (ISC_R_FILENOTFOUND);
+ case EACCES:
+ case EPERM:
+ return (ISC_R_NOPERM);
+ case EEXIST:
+ return (ISC_R_FILEEXISTS);
+ case EIO:
+ return (ISC_R_IOERROR);
+ case ENOMEM:
+ return (ISC_R_NOMEMORY);
+ case ENFILE:
+ case EMFILE:
+ return (ISC_R_TOOMANYOPENFILES);
+ case EPIPE:
+#ifdef ECONNRESET
+ case ECONNRESET:
+#endif
+#ifdef ECONNABORTED
+ case ECONNABORTED:
+#endif
+ return (ISC_R_CONNECTIONRESET);
+#ifdef ENOTCONN
+ case ENOTCONN:
+ return (ISC_R_NOTCONNECTED);
+#endif
+#ifdef ETIMEDOUT
+ case ETIMEDOUT:
+ return (ISC_R_TIMEDOUT);
+#endif
+#ifdef ENOBUFS
+ case ENOBUFS:
+ return (ISC_R_NORESOURCES);
+#endif
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+ return (ISC_R_FAMILYNOSUPPORT);
+#endif
+#ifdef ENETDOWN
+ case ENETDOWN:
+ return (ISC_R_NETDOWN);
+#endif
+#ifdef EHOSTDOWN
+ case EHOSTDOWN:
+ return (ISC_R_HOSTDOWN);
+#endif
+#ifdef ENETUNREACH
+ case ENETUNREACH:
+ return (ISC_R_NETUNREACH);
+#endif
+#ifdef EHOSTUNREACH
+ case EHOSTUNREACH:
+ return (ISC_R_HOSTUNREACH);
+#endif
+#ifdef EADDRINUSE
+ case EADDRINUSE:
+ return (ISC_R_ADDRINUSE);
+#endif
+ case EADDRNOTAVAIL:
+ return (ISC_R_ADDRNOTAVAIL);
+ case ECONNREFUSED:
+ return (ISC_R_CONNREFUSED);
+ default:
+ isc__strerror(posixerrno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(file, line, "unable to convert errno "
+ "to isc_result: %d: %s",
+ posixerrno, strbuf);
+ /*
+ * XXXDCL would be nice if perhaps this function could
+ * return the system's error string, so the caller
+ * might have something more descriptive than "unexpected
+ * error" to log with.
+ */
+ return (ISC_R_UNEXPECTED);
+ }
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/errno2result.h b/contrib/ntp/libntp/lib/isc/unix/errno2result.h
new file mode 100644
index 000000000000..1e49ed1d6c89
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/errno2result.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef UNIX_ERRNO2RESULT_H
+#define UNIX_ERRNO2RESULT_H 1
+
+/*! \file */
+
+/* XXXDCL this should be moved to lib/isc/include/isc/errno2result.h. */
+
+#include <errno.h> /* Provides errno. */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+#define isc__errno2result(x) isc___errno2result(x, __FILE__, __LINE__)
+
+isc_result_t
+isc___errno2result(int posixerrno, const char *file, unsigned int line);
+
+ISC_LANG_ENDDECLS
+
+#endif /* UNIX_ERRNO2RESULT_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/file.c b/contrib/ntp/libntp/lib/isc/unix/file.c
new file mode 100644
index 000000000000..9eda4a33bc80
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/file.c
@@ -0,0 +1,544 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Portions Copyright (c) 1987, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS 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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <time.h> /* Required for utimes on some platforms. */
+#include <unistd.h> /* Required for mkstemp on NetBSD. */
+
+
+#include <sys/stat.h>
+#include <sys/time.h>
+
+#include <isc/dir.h>
+#include <isc/file.h>
+#include <isc/log.h>
+#include <isc/mem.h>
+#include <isc/random.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+#include "errno2result.h"
+#include "ntp_stdlib.h" /* NTP change for strlcpy, strlcat */
+
+/*
+ * XXXDCL As the API for accessing file statistics undoubtedly gets expanded,
+ * it might be good to provide a mechanism that allows for the results
+ * of a previous stat() to be used again without having to do another stat,
+ * such as perl's mechanism of using "_" in place of a file name to indicate
+ * that the results of the last stat should be used. But then you get into
+ * annoying MP issues. BTW, Win32 has stat().
+ */
+static isc_result_t
+file_stats(const char *file, struct stat *stats) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(file != NULL);
+ REQUIRE(stats != NULL);
+
+ if (stat(file, stats) != 0)
+ result = isc__errno2result(errno);
+
+ return (result);
+}
+
+isc_result_t
+isc_file_getmodtime(const char *file, isc_time_t *itime) {
+ isc_result_t result;
+ struct stat stats;
+
+ REQUIRE(file != NULL);
+ REQUIRE(itime != NULL);
+
+ result = file_stats(file, &stats);
+
+ if (result == ISC_R_SUCCESS)
+ /*
+ * XXXDCL some operating systems provide nanoseconds, too,
+ * such as BSD/OS via st_mtimespec.
+ */
+ isc_time_set(itime, stats.st_mtime, 0);
+
+ return (result);
+}
+
+isc_result_t
+isc_file_settime(const char *file, isc_time_t *itime) {
+ struct timeval times[2];
+
+ REQUIRE(file != NULL && itime != NULL);
+
+ /*
+ * tv_sec is at least a 32 bit quantity on all platforms we're
+ * dealing with, but it is signed on most (all?) of them,
+ * so we need to make sure the high bit isn't set. This unfortunately
+ * loses when either:
+ * * tv_sec becomes a signed 64 bit integer but long is 32 bits
+ * and isc_time_seconds > LONG_MAX, or
+ * * isc_time_seconds is changed to be > 32 bits but long is 32 bits
+ * and isc_time_seconds has at least 33 significant bits.
+ */
+ times[0].tv_sec = times[1].tv_sec = (long)isc_time_seconds(itime);
+
+ /*
+ * Here is the real check for the high bit being set.
+ */
+ if ((times[0].tv_sec &
+ (1ULL << (sizeof(times[0].tv_sec) * CHAR_BIT - 1))) != 0)
+ return (ISC_R_RANGE);
+
+ /*
+ * isc_time_nanoseconds guarantees a value that divided by 1000 will
+ * fit into the minimum possible size tv_usec field. Unfortunately,
+ * we don't know what that type is so can't cast directly ... but
+ * we can at least cast to signed so the IRIX compiler shuts up.
+ */
+ times[0].tv_usec = times[1].tv_usec =
+ (isc_int32_t)(isc_time_nanoseconds(itime) / 1000);
+
+ if (utimes(file, times) < 0)
+ return (isc__errno2result(errno));
+
+ return (ISC_R_SUCCESS);
+}
+
+#undef TEMPLATE
+#define TEMPLATE "tmp-XXXXXXXXXX" /*%< 14 characters. */
+
+isc_result_t
+isc_file_mktemplate(const char *path, char *buf, size_t buflen) {
+ return (isc_file_template(path, TEMPLATE, buf, buflen));
+}
+
+isc_result_t
+isc_file_template(const char *path, const char *templet, char *buf,
+ size_t buflen) {
+ char *s;
+
+ REQUIRE(path != NULL);
+ REQUIRE(templet != NULL);
+ REQUIRE(buf != NULL);
+
+ s = strrchr(templet, '/');
+ if (s != NULL)
+ templet = s + 1;
+
+ s = strrchr(path, '/');
+
+ if (s != NULL) {
+ if ((s - path + 1 + strlen(templet) + 1) > buflen)
+ return (ISC_R_NOSPACE);
+
+ strlcpy(buf, path, buflen);
+ buf[s - path + 1] = '\0';
+ strlcat(buf, templet, buflen);
+ } else {
+ if ((strlen(templet) + 1) > buflen)
+ return (ISC_R_NOSPACE);
+
+ strlcpy(buf, templet, buflen);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static char alphnum[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
+
+isc_result_t
+isc_file_renameunique(const char *file, char *templet) {
+ char *x;
+ char *cp;
+ isc_uint32_t which;
+
+ REQUIRE(file != NULL);
+ REQUIRE(templet != NULL);
+
+ cp = templet;
+ while (*cp != '\0')
+ cp++;
+ if (cp == templet)
+ return (ISC_R_FAILURE);
+
+ x = cp--;
+ while (cp >= templet && *cp == 'X') {
+ isc_random_get(&which);
+ *cp = alphnum[which % (sizeof(alphnum) - 1)];
+ x = cp--;
+ }
+ while (link(file, templet) == -1) {
+ if (errno != EEXIST)
+ return (isc__errno2result(errno));
+ for (cp = x;;) {
+ char *t;
+ if (*cp == '\0')
+ return (ISC_R_FAILURE);
+ t = strchr(alphnum, *cp);
+ if (t == NULL || *++t == '\0')
+ *cp++ = alphnum[0];
+ else {
+ *cp = *t;
+ break;
+ }
+ }
+ }
+ if (unlink(file) < 0)
+ if (errno != ENOENT)
+ return (isc__errno2result(errno));
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_file_openunique(char *templet, FILE **fp) {
+ int mode = S_IWUSR|S_IRUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH;
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
+isc_file_openuniqueprivate(char *templet, FILE **fp) {
+ int mode = S_IWUSR|S_IRUSR;
+ return (isc_file_openuniquemode(templet, mode, fp));
+}
+
+isc_result_t
+isc_file_openuniquemode(char *templet, int mode, FILE **fp) {
+ int fd;
+ FILE *f;
+ isc_result_t result = ISC_R_SUCCESS;
+ char *x;
+ char *cp;
+ isc_uint32_t which;
+
+ REQUIRE(templet != NULL);
+ REQUIRE(fp != NULL && *fp == NULL);
+
+ cp = templet;
+ while (*cp != '\0')
+ cp++;
+ if (cp == templet)
+ return (ISC_R_FAILURE);
+
+ x = cp--;
+ while (cp >= templet && *cp == 'X') {
+ isc_random_get(&which);
+ *cp = alphnum[which % (sizeof(alphnum) - 1)];
+ x = cp--;
+ }
+
+
+ while ((fd = open(templet, O_RDWR|O_CREAT|O_EXCL, mode)) == -1) {
+ if (errno != EEXIST)
+ return (isc__errno2result(errno));
+ for (cp = x;;) {
+ char *t;
+ if (*cp == '\0')
+ return (ISC_R_FAILURE);
+ t = strchr(alphnum, *cp);
+ if (t == NULL || *++t == '\0')
+ *cp++ = alphnum[0];
+ else {
+ *cp = *t;
+ break;
+ }
+ }
+ }
+ f = fdopen(fd, "w+");
+ if (f == NULL) {
+ result = isc__errno2result(errno);
+ if (remove(templet) < 0) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_FILE, ISC_LOG_ERROR,
+ "remove '%s': failed", templet);
+ }
+ (void)close(fd);
+ } else
+ *fp = f;
+
+ return (result);
+}
+
+isc_result_t
+isc_file_remove(const char *filename) {
+ int r;
+
+ REQUIRE(filename != NULL);
+
+ r = unlink(filename);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+isc_result_t
+isc_file_rename(const char *oldname, const char *newname) {
+ int r;
+
+ REQUIRE(oldname != NULL);
+ REQUIRE(newname != NULL);
+
+ r = rename(oldname, newname);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+isc_boolean_t
+isc_file_exists(const char *pathname) {
+ struct stat stats;
+
+ REQUIRE(pathname != NULL);
+
+ return (ISC_TF(file_stats(pathname, &stats) == ISC_R_SUCCESS));
+}
+
+isc_result_t
+isc_file_isplainfile(const char *filename) {
+ /*
+ * This function returns success if filename is a plain file.
+ */
+ struct stat filestat;
+ memset(&filestat,0,sizeof(struct stat));
+
+ if ((stat(filename, &filestat)) == -1)
+ return(isc__errno2result(errno));
+
+ if(! S_ISREG(filestat.st_mode))
+ return(ISC_R_INVALIDFILE);
+
+ return(ISC_R_SUCCESS);
+}
+
+isc_boolean_t
+isc_file_isabsolute(const char *filename) {
+ REQUIRE(filename != NULL);
+ return (ISC_TF(filename[0] == '/'));
+}
+
+isc_boolean_t
+isc_file_iscurrentdir(const char *filename) {
+ REQUIRE(filename != NULL);
+ return (ISC_TF(filename[0] == '.' && filename[1] == '\0'));
+}
+
+isc_boolean_t
+isc_file_ischdiridempotent(const char *filename) {
+ REQUIRE(filename != NULL);
+ if (isc_file_isabsolute(filename))
+ return (ISC_TRUE);
+ if (isc_file_iscurrentdir(filename))
+ return (ISC_TRUE);
+ return (ISC_FALSE);
+}
+
+const char *
+isc_file_basename(const char *filename) {
+ char *s;
+
+ REQUIRE(filename != NULL);
+
+ s = strrchr(filename, '/');
+ if (s == NULL)
+ return (filename);
+
+ return (s + 1);
+}
+
+isc_result_t
+isc_file_progname(const char *filename, char *buf, size_t buflen) {
+ const char *base;
+ size_t len;
+
+ REQUIRE(filename != NULL);
+ REQUIRE(buf != NULL);
+
+ base = isc_file_basename(filename);
+ len = strlen(base) + 1;
+
+ if (len > buflen)
+ return (ISC_R_NOSPACE);
+ memcpy(buf, base, len);
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Put the absolute name of the current directory into 'dirname', which is
+ * a buffer of at least 'length' characters. End the string with the
+ * appropriate path separator, such that the final product could be
+ * concatenated with a relative pathname to make a valid pathname string.
+ */
+static isc_result_t
+dir_current(char *dirname, size_t length) {
+ char *cwd;
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(dirname != NULL);
+ REQUIRE(length > 0U);
+
+ cwd = getcwd(dirname, length);
+
+ if (cwd == NULL) {
+ if (errno == ERANGE)
+ result = ISC_R_NOSPACE;
+ else
+ result = isc__errno2result(errno);
+ } else {
+ if (strlen(dirname) + 1 == length)
+ result = ISC_R_NOSPACE;
+ else if (dirname[1] != '\0')
+ strlcat(dirname, "/", length);
+ }
+
+ return (result);
+}
+
+isc_result_t
+isc_file_absolutepath(const char *filename, char *path, size_t pathlen) {
+ isc_result_t result;
+ result = dir_current(path, pathlen);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ if (strlen(path) + strlen(filename) + 1 > pathlen)
+ return (ISC_R_NOSPACE);
+ strlcat(path, filename, pathlen);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_file_truncate(const char *filename, isc_offset_t size) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ if (truncate(filename, size) < 0)
+ result = isc__errno2result(errno);
+ return (result);
+}
+
+isc_result_t
+isc_file_safecreate(const char *filename, FILE **fp) {
+ isc_result_t result;
+ int flags;
+ struct stat sb;
+ FILE *f;
+ int fd;
+
+ REQUIRE(filename != NULL);
+ REQUIRE(fp != NULL && *fp == NULL);
+
+ result = file_stats(filename, &sb);
+ if (result == ISC_R_SUCCESS) {
+ if ((sb.st_mode & S_IFREG) == 0)
+ return (ISC_R_INVALIDFILE);
+ flags = O_WRONLY | O_TRUNC;
+ } else if (result == ISC_R_FILENOTFOUND) {
+ flags = O_WRONLY | O_CREAT | O_EXCL;
+ } else
+ return (result);
+
+ fd = open(filename, flags, S_IRUSR | S_IWUSR);
+ if (fd == -1)
+ return (isc__errno2result(errno));
+
+ f = fdopen(fd, "w");
+ if (f == NULL) {
+ result = isc__errno2result(errno);
+ close(fd);
+ return (result);
+ }
+
+ *fp = f;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_file_splitpath(isc_mem_t *mctx, char *path, char **dirnam, char **basenam)
+{
+ char *dir, *file, *slash;
+
+ REQUIRE(path != NULL);
+
+ slash = strrchr(path, '/');
+
+ if (slash == path) {
+ file = ++slash;
+ dir = isc_mem_strdup(mctx, "/");
+ } else if (slash != NULL) {
+ file = ++slash;
+ dir = isc_mem_allocate(mctx, slash - path);
+ if (dir != NULL)
+ strlcpy(dir, path, slash - path);
+ } else {
+ file = path;
+ dir = isc_mem_strdup(mctx, ".");
+ }
+
+ if (dir == NULL)
+ return (ISC_R_NOMEMORY);
+
+ if (*file == '\0') {
+ isc_mem_free(mctx, dir);
+ return (ISC_R_INVALIDFILE);
+ }
+
+ *dirnam = dir;
+ *basenam = file;
+
+ return (ISC_R_SUCCESS);
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/ifiter_getifaddrs.c b/contrib/ntp/libntp/lib/isc/unix/ifiter_getifaddrs.c
new file mode 100644
index 000000000000..ad7c5f85c8ec
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/ifiter_getifaddrs.c
@@ -0,0 +1,283 @@
+/*
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ifiter_getifaddrs.c,v 1.13 2009/09/24 23:48:13 tbox Exp $ */
+
+/*! \file
+ * \brief
+ * Obtain the list of network interfaces using the getifaddrs(3) library.
+ */
+
+#include <ifaddrs.h>
+
+/*% Iterator Magic */
+#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'G')
+/*% Valid Iterator */
+#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC)
+
+#ifdef __linux
+static isc_boolean_t seenv6 = ISC_FALSE;
+#endif
+
+/*% Iterator structure */
+struct isc_interfaceiter {
+ unsigned int magic; /*%< Magic number. */
+ isc_mem_t *mctx;
+ void *buf; /*%< (unused) */
+ unsigned int bufsize; /*%< (always 0) */
+ struct ifaddrs *ifaddrs; /*%< List of ifaddrs */
+ struct ifaddrs *pos; /*%< Ptr to current ifaddr */
+ isc_interface_t current; /*%< Current interface data. */
+ isc_result_t result; /*%< Last result code. */
+#ifdef __linux
+ FILE * proc;
+ char entry[ISC_IF_INET6_SZ];
+ isc_result_t valid;
+#endif
+};
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+ isc_interfaceiter_t *iter;
+ isc_result_t result;
+ char strbuf[ISC_STRERRORSIZE];
+ int trys, ret;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(iterp != NULL);
+ REQUIRE(*iterp == NULL);
+
+ iter = isc_mem_get(mctx, sizeof(*iter));
+ if (iter == NULL)
+ return (ISC_R_NOMEMORY);
+
+ iter->mctx = mctx;
+ iter->buf = NULL;
+ iter->bufsize = 0;
+ iter->ifaddrs = NULL;
+#ifdef __linux
+ /*
+ * Only open "/proc/net/if_inet6" if we have never seen a IPv6
+ * address returned by getifaddrs().
+ */
+ if (!seenv6) {
+ iter->proc = fopen("/proc/net/if_inet6", "r");
+ if (iter->proc == NULL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_WARNING,
+ "failed to open /proc/net/if_inet6");
+ }
+ } else
+ iter->proc = NULL;
+ iter->valid = ISC_R_FAILURE;
+#endif
+
+ /* If interrupted, try again */
+ for (trys = 0; trys < 3; trys++) {
+ if ((ret = getifaddrs(&iter->ifaddrs)) >= 0)
+ break;
+ if (errno != EINTR)
+ break;
+ }
+ if (ret < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "getting interface addresses: %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERGETIFADDRS,
+ ISC_MSG_GETIFADDRS,
+ "getifaddrs"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto failure;
+ }
+
+ /*
+ * A newly created iterator has an undefined position
+ * until isc_interfaceiter_first() is called.
+ */
+ iter->pos = NULL;
+ iter->result = ISC_R_FAILURE;
+
+ iter->magic = IFITER_MAGIC;
+ *iterp = iter;
+ return (ISC_R_SUCCESS);
+
+ failure:
+#ifdef __linux
+ if (iter->proc != NULL)
+ fclose(iter->proc);
+#endif
+ if (iter->ifaddrs != NULL) /* just in case */
+ freeifaddrs(iter->ifaddrs);
+ isc_mem_put(mctx, iter, sizeof(*iter));
+ return (result);
+}
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family,
+ * return ISC_R_IGNORE.
+ */
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+ struct ifaddrs *ifa;
+ int family;
+ unsigned int namelen;
+
+ REQUIRE(VALID_IFITER(iter));
+
+ ifa = iter->pos;
+
+#ifdef __linux
+ /*
+ * [Bug 2792]
+ * burnicki: iter->pos is usually never NULL here (anymore?),
+ * so linux_if_inet6_current(iter) is never called here.
+ * However, that routine would check (under Linux), if the
+ * interface is in a tentative state, e.g. if there's no link
+ * yet but an IPv6 address has already be assigned.
+ */
+ if (iter->pos == NULL)
+ return (linux_if_inet6_current(iter));
+#endif
+
+ INSIST(ifa != NULL);
+ INSIST(ifa->ifa_name != NULL);
+
+
+#ifdef IFF_RUNNING
+ /*
+ * [Bug 2792]
+ * burnicki: if the interface is not running then
+ * it may be in a tentative state. See above.
+ */
+ if ((ifa->ifa_flags & IFF_RUNNING) == 0)
+ return (ISC_R_IGNORE);
+#endif
+
+ if (ifa->ifa_addr == NULL)
+ return (ISC_R_IGNORE);
+
+ family = ifa->ifa_addr->sa_family;
+ if (family != AF_INET && family != AF_INET6)
+ return (ISC_R_IGNORE);
+
+#ifdef __linux
+ if (family == AF_INET6)
+ seenv6 = ISC_TRUE;
+#endif
+
+ memset(&iter->current, 0, sizeof(iter->current));
+
+ namelen = strlen(ifa->ifa_name);
+ if (namelen > sizeof(iter->current.name) - 1)
+ namelen = sizeof(iter->current.name) - 1;
+
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ memcpy(iter->current.name, ifa->ifa_name, namelen);
+
+ iter->current.flags = 0;
+
+ if ((ifa->ifa_flags & IFF_UP) != 0)
+ iter->current.flags |= INTERFACE_F_UP;
+
+ if ((ifa->ifa_flags & IFF_POINTOPOINT) != 0)
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+
+ if ((ifa->ifa_flags & IFF_LOOPBACK) != 0)
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+ if ((ifa->ifa_flags & IFF_BROADCAST) != 0)
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+
+#ifdef IFF_MULTICAST
+ if ((ifa->ifa_flags & IFF_MULTICAST) != 0)
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+#endif
+
+ iter->current.af = family;
+
+ get_addr(family, &iter->current.address, ifa->ifa_addr, ifa->ifa_name);
+
+ if (ifa->ifa_netmask != NULL)
+ get_addr(family, &iter->current.netmask, ifa->ifa_netmask,
+ ifa->ifa_name);
+
+ if (ifa->ifa_dstaddr != NULL &&
+ (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
+ get_addr(family, &iter->current.dstaddress, ifa->ifa_dstaddr,
+ ifa->ifa_name);
+
+ if (ifa->ifa_broadaddr != NULL &&
+ (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
+ get_addr(family, &iter->current.broadcast, ifa->ifa_broadaddr,
+ ifa->ifa_name);
+
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Step the iterator to the next interface. Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored. Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+
+ if (iter->pos != NULL)
+ iter->pos = iter->pos->ifa_next;
+ if (iter->pos == NULL) {
+#ifdef __linux
+ if (!seenv6)
+ return (linux_if_inet6_next(iter));
+#endif
+ return (ISC_R_NOMORE);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+internal_destroy(isc_interfaceiter_t *iter) {
+
+#ifdef __linux
+ if (iter->proc != NULL)
+ fclose(iter->proc);
+ iter->proc = NULL;
+#endif
+ if (iter->ifaddrs)
+ freeifaddrs(iter->ifaddrs);
+ iter->ifaddrs = NULL;
+}
+
+static
+void internal_first(isc_interfaceiter_t *iter) {
+
+#ifdef __linux
+ linux_if_inet6_first(iter);
+#endif
+ iter->pos = iter->ifaddrs;
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/ifiter_ioctl.c b/contrib/ntp/libntp/lib/isc/unix/ifiter_ioctl.c
new file mode 100644
index 000000000000..c8e4970e6b33
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/ifiter_ioctl.c
@@ -0,0 +1,1032 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ifiter_ioctl.c,v 1.62 2009/01/18 23:48:14 tbox Exp $ */
+
+/*! \file
+ * \brief
+ * Obtain the list of network interfaces using the SIOCGLIFCONF ioctl.
+ * See netintro(4).
+ */
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+#ifdef ISC_PLATFORM_HAVEIF_LADDRCONF
+#define lifc_len iflc_len
+#define lifc_buf iflc_buf
+#define lifc_req iflc_req
+#define LIFCONF if_laddrconf
+#else
+#define ISC_HAVE_LIFC_FAMILY 1
+#define ISC_HAVE_LIFC_FLAGS 1
+#define LIFCONF lifconf
+#endif
+
+#ifdef ISC_PLATFORM_HAVEIF_LADDRREQ
+#define lifr_addr iflr_addr
+#define lifr_name iflr_name
+#define lifr_dstaddr iflr_dstaddr
+#define lifr_broadaddr iflr_broadaddr
+#define lifr_flags iflr_flags
+#define lifr_index iflr_index
+#define ss_family sa_family
+#define LIFREQ if_laddrreq
+#else
+#define LIFREQ lifreq
+#endif
+#endif
+
+#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'T')
+#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC)
+
+struct isc_interfaceiter {
+ unsigned int magic; /* Magic number. */
+ isc_mem_t *mctx;
+ int mode;
+ int socket;
+ struct ifconf ifc;
+ void *buf; /* Buffer for sysctl data. */
+ unsigned int bufsize; /* Bytes allocated. */
+ unsigned int pos; /* Current offset in
+ SIOCGIFCONF data */
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ int socket6;
+ struct LIFCONF lifc;
+ void *buf6; /* Buffer for sysctl data. */
+ unsigned int bufsize6; /* Bytes allocated. */
+ unsigned int pos6; /* Current offset in
+ SIOCGLIFCONF data */
+ isc_result_t result6; /* Last result code. */
+ isc_boolean_t first6;
+#endif
+#ifdef HAVE_TRUCLUSTER
+ int clua_context; /* Cluster alias context */
+ isc_boolean_t clua_done;
+ struct sockaddr clua_sa;
+#endif
+#ifdef __linux
+ FILE * proc;
+ char entry[ISC_IF_INET6_SZ];
+ isc_result_t valid;
+#endif
+ isc_interface_t current; /* Current interface data. */
+ isc_result_t result; /* Last result code. */
+};
+
+#ifdef HAVE_TRUCLUSTER
+#include <clua/clua.h>
+#include <sys/socket.h>
+#endif
+
+
+/*%
+ * Size of buffer for SIOCGLIFCONF, in bytes. We assume no sane system
+ * will have more than a megabyte of interface configuration data.
+ */
+#define IFCONF_BUFSIZE_INITIAL 4096
+#define IFCONF_BUFSIZE_MAX 1048576
+
+#ifdef __linux
+#ifndef IF_NAMESIZE
+# ifdef IFNAMSIZ
+# define IF_NAMESIZE IFNAMSIZ
+# else
+# define IF_NAMESIZE 16
+# endif
+#endif
+#endif
+
+/* Silence a warning when this file is #included */
+int
+isc_ioctl(int fildes, int req, char *arg);
+
+int
+isc_ioctl(int fildes, int req, char *arg) {
+ int trys;
+ int ret;
+
+ for (trys = 0; trys < 3; trys++) {
+ if ((ret = ioctl(fildes, req, arg)) < 0) {
+ if (errno == EINTR)
+ continue;
+ }
+ break;
+ }
+ return (ret);
+}
+
+static isc_result_t
+getbuf4(isc_interfaceiter_t *iter) {
+ char strbuf[ISC_STRERRORSIZE];
+
+ iter->bufsize = IFCONF_BUFSIZE_INITIAL;
+
+ for (;;) {
+ iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
+ if (iter->buf == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(&iter->ifc.ifc_len, 0, sizeof(iter->ifc.ifc_len));
+ iter->ifc.ifc_len = iter->bufsize;
+ iter->ifc.ifc_buf = iter->buf;
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion". It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFCONF, (char *)&iter->ifc)
+ == -1) {
+ if (errno != EINVAL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETIFCONFIG,
+ "get interface "
+ "configuration: %s"),
+ strbuf);
+ goto unexpected;
+ }
+ /*
+ * EINVAL. Retry with a bigger buffer.
+ */
+ } else {
+ /*
+ * The ioctl succeeded.
+ * Some OS's just return what will fit rather
+ * than set EINVAL if the buffer is too small
+ * to fit all the interfaces in. If
+ * ifc.lifc_len is too near to the end of the
+ * buffer we will grow it just in case and
+ * retry.
+ */
+ if (iter->ifc.ifc_len + 2 * sizeof(struct ifreq)
+ < iter->bufsize)
+ break;
+ }
+ if (iter->bufsize >= IFCONF_BUFSIZE_MAX) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_BUFFERMAX,
+ "get interface "
+ "configuration: "
+ "maximum buffer "
+ "size exceeded"));
+ goto unexpected;
+ }
+ isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+
+ iter->bufsize *= 2;
+ }
+ return (ISC_R_SUCCESS);
+
+ unexpected:
+ isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+ iter->buf = NULL;
+ return (ISC_R_UNEXPECTED);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+getbuf6(isc_interfaceiter_t *iter) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc_result_t result;
+
+ iter->bufsize6 = IFCONF_BUFSIZE_INITIAL;
+
+ for (;;) {
+ iter->buf6 = isc_mem_get(iter->mctx, iter->bufsize6);
+ if (iter->buf6 == NULL)
+ return (ISC_R_NOMEMORY);
+
+ memset(&iter->lifc, 0, sizeof(iter->lifc));
+#ifdef ISC_HAVE_LIFC_FAMILY
+ iter->lifc.lifc_family = AF_INET6;
+#endif
+#ifdef ISC_HAVE_LIFC_FLAGS
+ iter->lifc.lifc_flags = 0;
+#endif
+ iter->lifc.lifc_len = iter->bufsize6;
+ iter->lifc.lifc_buf = iter->buf6;
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion". It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket6, SIOCGLIFCONF, (char *)&iter->lifc)
+ == -1) {
+#ifdef __hpux
+ /*
+ * IPv6 interface scanning is not available on all
+ * kernels w/ IPv6 sockets.
+ */
+ if (errno == ENOENT) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE,
+ ISC_LOG_DEBUG(1),
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETIFCONFIG,
+ "get interface "
+ "configuration: %s"),
+ strbuf);
+ result = ISC_R_FAILURE;
+ goto cleanup;
+ }
+#endif
+ if (errno != EINVAL) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETIFCONFIG,
+ "get interface "
+ "configuration: %s"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto cleanup;
+ }
+ /*
+ * EINVAL. Retry with a bigger buffer.
+ */
+ } else {
+ /*
+ * The ioctl succeeded.
+ * Some OS's just return what will fit rather
+ * than set EINVAL if the buffer is too small
+ * to fit all the interfaces in. If
+ * ifc.ifc_len is too near to the end of the
+ * buffer we will grow it just in case and
+ * retry.
+ */
+ if (iter->lifc.lifc_len + 2 * sizeof(struct LIFREQ)
+ < iter->bufsize6)
+ break;
+ }
+ if (iter->bufsize6 >= IFCONF_BUFSIZE_MAX) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_BUFFERMAX,
+ "get interface "
+ "configuration: "
+ "maximum buffer "
+ "size exceeded"));
+ result = ISC_R_UNEXPECTED;
+ goto cleanup;
+ }
+ isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+
+ iter->bufsize6 *= 2;
+ }
+
+ if (iter->lifc.lifc_len != 0)
+ iter->mode = 6;
+ return (ISC_R_SUCCESS);
+
+ cleanup:
+ isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+ iter->buf6 = NULL;
+ return (result);
+}
+#endif
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+ isc_interfaceiter_t *iter;
+ isc_result_t result;
+ char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(iterp != NULL);
+ REQUIRE(*iterp == NULL);
+
+ iter = isc_mem_get(mctx, sizeof(*iter));
+ if (iter == NULL)
+ return (ISC_R_NOMEMORY);
+
+ iter->mctx = mctx;
+ iter->mode = 4;
+ iter->buf = NULL;
+ iter->pos = (unsigned int) -1;
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ iter->buf6 = NULL;
+ iter->pos6 = (unsigned int) -1;
+ iter->result6 = ISC_R_NOMORE;
+ iter->socket6 = -1;
+ iter->first6 = ISC_FALSE;
+#endif
+
+ /*
+ * Get the interface configuration, allocating more memory if
+ * necessary.
+ */
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ result = isc_net_probeipv6();
+ if (result == ISC_R_SUCCESS) {
+ /*
+ * Create an unbound datagram socket to do the SIOCGLIFCONF
+ * ioctl on. HP/UX requires an AF_INET6 socket for
+ * SIOCGLIFCONF to get IPv6 addresses.
+ */
+ if ((iter->socket6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_MAKESCANSOCKET,
+ "making interface "
+ "scan socket: %s"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto socket6_failure;
+ }
+ result = iter->result6 = getbuf6(iter);
+ if (result != ISC_R_NOTIMPLEMENTED && result != ISC_R_SUCCESS)
+ goto ioctl6_failure;
+ }
+#endif
+ if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_MAKESCANSOCKET,
+ "making interface "
+ "scan socket: %s"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto socket_failure;
+ }
+ result = getbuf4(iter);
+ if (result != ISC_R_SUCCESS)
+ goto ioctl_failure;
+
+ /*
+ * A newly created iterator has an undefined position
+ * until isc_interfaceiter_first() is called.
+ */
+#ifdef HAVE_TRUCLUSTER
+ iter->clua_context = -1;
+ iter->clua_done = ISC_TRUE;
+#endif
+#ifdef __linux
+ iter->proc = fopen("/proc/net/if_inet6", "r");
+ iter->valid = ISC_R_FAILURE;
+#endif
+ iter->result = ISC_R_FAILURE;
+
+ iter->magic = IFITER_MAGIC;
+ *iterp = iter;
+ return (ISC_R_SUCCESS);
+
+ ioctl_failure:
+ if (iter->buf != NULL)
+ isc_mem_put(mctx, iter->buf, iter->bufsize);
+ (void) close(iter->socket);
+
+ socket_failure:
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ if (iter->buf6 != NULL)
+ isc_mem_put(mctx, iter->buf6, iter->bufsize6);
+ ioctl6_failure:
+ if (iter->socket6 != -1)
+ (void) close(iter->socket6);
+ socket6_failure:
+#endif
+
+ isc_mem_put(mctx, iter, sizeof(*iter));
+ return (result);
+}
+
+#ifdef HAVE_TRUCLUSTER
+static void
+get_inaddr(isc_netaddr_t *dst, struct in_addr *src) {
+ dst->family = AF_INET;
+ memcpy(&dst->type.in, src, sizeof(struct in_addr));
+}
+
+static isc_result_t
+internal_current_clusteralias(isc_interfaceiter_t *iter) {
+ struct clua_info ci;
+ if (clua_getaliasinfo(&iter->clua_sa, &ci) != CLUA_SUCCESS)
+ return (ISC_R_IGNORE);
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = iter->clua_sa.sa_family;
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ sprintf(iter->current.name, "clua%d", ci.aliasid);
+ iter->current.flags = INTERFACE_F_UP;
+ get_inaddr(&iter->current.address, &ci.addr);
+ get_inaddr(&iter->current.netmask, &ci.netmask);
+ return (ISC_R_SUCCESS);
+}
+#endif
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family, or if
+ * some operation on it fails, return ISC_R_IGNORE to make
+ * the higher-level iterator code ignore it.
+ */
+
+static isc_result_t
+internal_current4(isc_interfaceiter_t *iter) {
+ struct ifreq *ifrp;
+ struct ifreq ifreq;
+ int family;
+ char strbuf[ISC_STRERRORSIZE];
+#if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR)
+ struct lifreq lifreq;
+#else
+ char sabuf[256];
+#endif
+ int i, bits, prefixlen;
+
+ REQUIRE(VALID_IFITER(iter));
+
+ if (iter->ifc.ifc_len == 0 ||
+ iter->pos == (unsigned int)iter->ifc.ifc_len) {
+#ifdef __linux
+ return (linux_if_inet6_current(iter));
+#else
+ return (ISC_R_NOMORE);
+#endif
+ }
+
+ INSIST( iter->pos < (unsigned int) iter->ifc.ifc_len);
+
+ ifrp = (void *)((char *) iter->ifc.ifc_req + iter->pos);
+
+ memset(&ifreq, 0, sizeof(ifreq));
+ memcpy(&ifreq, ifrp, sizeof(ifreq));
+
+ family = ifreq.ifr_addr.sa_family;
+#if defined(ISC_PLATFORM_HAVEIPV6)
+ if (family != AF_INET && family != AF_INET6)
+#else
+ if (family != AF_INET)
+#endif
+ return (ISC_R_IGNORE);
+
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = family;
+
+ INSIST(sizeof(ifreq.ifr_name) <= sizeof(iter->current.name));
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ memcpy(iter->current.name, ifreq.ifr_name, sizeof(ifreq.ifr_name));
+
+ get_addr(family, &iter->current.address,
+ (struct sockaddr *)&ifrp->ifr_addr, ifreq.ifr_name);
+
+ /*
+ * If the interface does not have a address ignore it.
+ */
+ switch (family) {
+ case AF_INET:
+ if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY))
+ return (ISC_R_IGNORE);
+ break;
+ case AF_INET6:
+ if (memcmp(&iter->current.address.type.in6, &in6addr_any,
+ sizeof(in6addr_any)) == 0)
+ return (ISC_R_IGNORE);
+ break;
+ }
+
+ /*
+ * Get interface flags.
+ */
+
+ iter->current.flags = 0;
+
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFFLAGS, (char *) &ifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "%s: getting interface flags: %s",
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+
+ if ((ifreq.ifr_flags & IFF_UP) != 0)
+ iter->current.flags |= INTERFACE_F_UP;
+
+#ifdef IFF_POINTOPOINT
+ if ((ifreq.ifr_flags & IFF_POINTOPOINT) != 0)
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+#endif
+
+ if ((ifreq.ifr_flags & IFF_LOOPBACK) != 0)
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+ if ((ifreq.ifr_flags & IFF_BROADCAST) != 0)
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+
+#ifdef IFF_MULTICAST
+ if ((ifreq.ifr_flags & IFF_MULTICAST) != 0)
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+#endif
+
+ if (family == AF_INET)
+ goto inet;
+
+#if !defined(ISC_PLATFORM_HAVEIF_LADDRREQ) && defined(SIOCGLIFADDR)
+ memset(&lifreq, 0, sizeof(lifreq));
+ memcpy(lifreq.lifr_name, iter->current.name, sizeof(lifreq.lifr_name));
+ memcpy(&lifreq.lifr_addr, &iter->current.address.type.in6,
+ sizeof(iter->current.address.type.in6));
+
+ if (isc_ioctl(iter->socket, SIOCGLIFADDR, &lifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "%s: getting interface address: %s",
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ prefixlen = lifreq.lifr_addrlen;
+#else
+ isc_netaddr_format(&iter->current.address, sabuf, sizeof(sabuf));
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE,
+ ISC_LOG_INFO,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETIFCONFIG,
+ "prefix length for %s is unknown "
+ "(assume 128)"), sabuf);
+ prefixlen = 128;
+#endif
+
+ /*
+ * Netmask already zeroed.
+ */
+ iter->current.netmask.family = family;
+ for (i = 0; i < 16; i++) {
+ if (prefixlen > 8) {
+ bits = 0;
+ prefixlen -= 8;
+ } else {
+ bits = 8 - prefixlen;
+ prefixlen = 0;
+ }
+ iter->current.netmask.type.in6.s6_addr[i] = (~0 << bits) & 0xff;
+ }
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+
+ inet:
+ if (family != AF_INET)
+ return (ISC_R_IGNORE);
+#ifdef IFF_POINTOPOINT
+ /*
+ * If the interface is point-to-point, get the destination address.
+ */
+ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFDSTADDR, (char *)&ifreq)
+ < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETDESTADDR,
+ "%s: getting "
+ "destination address: %s"),
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.dstaddress,
+ (struct sockaddr *)&ifreq.ifr_dstaddr, ifreq.ifr_name);
+ }
+#endif
+
+ if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFBRDADDR, (char *)&ifreq)
+ < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETBCSTADDR,
+ "%s: getting "
+ "broadcast address: %s"),
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.broadcast,
+ (struct sockaddr *)&ifreq.ifr_broadaddr, ifreq.ifr_name);
+ }
+
+ /*
+ * Get the network mask.
+ */
+ memset(&ifreq, 0, sizeof(ifreq));
+ memcpy(&ifreq, ifrp, sizeof(ifreq));
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETNETMASK,
+ "%s: getting netmask: %s"),
+ ifreq.ifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.netmask,
+ (struct sockaddr *)&ifreq.ifr_addr, ifreq.ifr_name);
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+internal_current6(isc_interfaceiter_t *iter) {
+ struct LIFREQ *ifrp;
+ struct LIFREQ lifreq;
+ int family;
+ char strbuf[ISC_STRERRORSIZE];
+ int fd;
+
+ REQUIRE(VALID_IFITER(iter));
+ if (iter->result6 != ISC_R_SUCCESS)
+ return (iter->result6);
+ REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
+
+ ifrp = (void *)((char *)iter->lifc.lifc_req + iter->pos6);
+
+ memset(&lifreq, 0, sizeof(lifreq));
+ memcpy(&lifreq, ifrp, sizeof(lifreq));
+
+ family = lifreq.lifr_addr.ss_family;
+#ifdef ISC_PLATFORM_HAVEIPV6
+ if (family != AF_INET && family != AF_INET6)
+#else
+ if (family != AF_INET)
+#endif
+ return (ISC_R_IGNORE);
+
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = family;
+
+ INSIST(sizeof(lifreq.lifr_name) <= sizeof(iter->current.name));
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ memcpy(iter->current.name, lifreq.lifr_name, sizeof(lifreq.lifr_name));
+
+ get_addr(family, &iter->current.address,
+ (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
+
+ if (isc_netaddr_islinklocal(&iter->current.address))
+ isc_netaddr_setzone(&iter->current.address,
+ (isc_uint32_t)lifreq.lifr_index);
+
+ /*
+ * If the interface does not have a address ignore it.
+ */
+ switch (family) {
+ case AF_INET:
+ if (iter->current.address.type.in.s_addr == htonl(INADDR_ANY))
+ return (ISC_R_IGNORE);
+ break;
+ case AF_INET6:
+ if (memcmp(&iter->current.address.type.in6, &in6addr_any,
+ sizeof(in6addr_any)) == 0)
+ return (ISC_R_IGNORE);
+ break;
+ }
+
+ /*
+ * Get interface flags.
+ */
+
+ iter->current.flags = 0;
+
+ if (family == AF_INET6)
+ fd = iter->socket6;
+ else
+ fd = iter->socket;
+
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(fd, SIOCGLIFFLAGS, (char *) &lifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "%s: getting interface flags: %s",
+ lifreq.lifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+
+ if ((lifreq.lifr_flags & IFF_UP) != 0)
+ iter->current.flags |= INTERFACE_F_UP;
+
+#ifdef IFF_POINTOPOINT
+ if ((lifreq.lifr_flags & IFF_POINTOPOINT) != 0)
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+#endif
+
+ if ((lifreq.lifr_flags & IFF_LOOPBACK) != 0)
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+ if ((lifreq.lifr_flags & IFF_BROADCAST) != 0) {
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+ }
+
+#ifdef IFF_MULTICAST
+ if ((lifreq.lifr_flags & IFF_MULTICAST) != 0) {
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+ }
+#endif
+
+#ifdef IFF_POINTOPOINT
+ /*
+ * If the interface is point-to-point, get the destination address.
+ */
+ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0) {
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(fd, SIOCGLIFDSTADDR, (char *)&lifreq)
+ < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETDESTADDR,
+ "%s: getting "
+ "destination address: %s"),
+ lifreq.lifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.dstaddress,
+ (struct sockaddr *)&lifreq.lifr_dstaddr,
+ lifreq.lifr_name);
+ }
+#endif
+
+#ifdef SIOCGLIFBRDADDR
+ if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0) {
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(iter->socket, SIOCGLIFBRDADDR, (char *)&lifreq)
+ < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETBCSTADDR,
+ "%s: getting "
+ "broadcast address: %s"),
+ lifreq.lifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.broadcast,
+ (struct sockaddr *)&lifreq.lifr_broadaddr,
+ lifreq.lifr_name);
+ }
+#endif /* SIOCGLIFBRDADDR */
+
+ /*
+ * Get the network mask. Netmask already zeroed.
+ */
+ memset(&lifreq, 0, sizeof(lifreq));
+ memcpy(&lifreq, ifrp, sizeof(lifreq));
+
+#ifdef lifr_addrlen
+ /*
+ * Special case: if the system provides lifr_addrlen member, the
+ * netmask of an IPv6 address can be derived from the length, since
+ * an IPv6 address always has a contiguous mask.
+ */
+ if (family == AF_INET6) {
+ int i, bits;
+
+ iter->current.netmask.family = family;
+ for (i = 0; i < lifreq.lifr_addrlen; i += 8) {
+ bits = lifreq.lifr_addrlen - i;
+ bits = (bits < 8) ? (8 - bits) : 0;
+ iter->current.netmask.type.in6.s6_addr[i / 8] =
+ (~0 << bits) & 0xff;
+ }
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+ }
+#endif
+
+ /*
+ * Ignore the HP/UX warning about "integer overflow during
+ * conversion. It comes from its own macro definition,
+ * and is really hard to shut up.
+ */
+ if (isc_ioctl(fd, SIOCGLIFNETMASK, (char *)&lifreq) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERIOCTL,
+ ISC_MSG_GETNETMASK,
+ "%s: getting netmask: %s"),
+ lifreq.lifr_name, strbuf);
+ return (ISC_R_IGNORE);
+ }
+ get_addr(family, &iter->current.netmask,
+ (struct sockaddr *)&lifreq.lifr_addr, lifreq.lifr_name);
+
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ iter->current.ifindex = if_nametoindex(iter->current.name);
+#endif
+ return (ISC_R_SUCCESS);
+}
+#endif
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ if (iter->mode == 6) {
+ iter->result6 = internal_current6(iter);
+ if (iter->result6 != ISC_R_NOMORE)
+ return (iter->result6);
+ }
+#endif
+#ifdef HAVE_TRUCLUSTER
+ if (!iter->clua_done)
+ return(internal_current_clusteralias(iter));
+#endif
+ return (internal_current4(iter));
+}
+
+/*
+ * Step the iterator to the next interface. Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored. Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next4(isc_interfaceiter_t *iter) {
+#ifdef ISC_PLATFORM_HAVESALEN
+ struct ifreq *ifrp;
+#endif
+
+ if (iter->pos < (unsigned int) iter->ifc.ifc_len) {
+#ifdef ISC_PLATFORM_HAVESALEN
+ ifrp = (struct ifreq *)((char *) iter->ifc.ifc_req + iter->pos);
+
+ if (ifrp->ifr_addr.sa_len > sizeof(struct sockaddr))
+ iter->pos += sizeof(ifrp->ifr_name) +
+ ifrp->ifr_addr.sa_len;
+ else
+#endif
+ iter->pos += sizeof(struct ifreq);
+
+ } else {
+ INSIST(iter->pos == (unsigned int) iter->ifc.ifc_len);
+#ifdef __linux
+ return (linux_if_inet6_next(iter));
+#else
+ return (ISC_R_NOMORE);
+#endif
+ }
+ return (ISC_R_SUCCESS);
+}
+
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+static isc_result_t
+internal_next6(isc_interfaceiter_t *iter) {
+#ifdef ISC_PLATFORM_HAVESALEN
+ struct LIFREQ *ifrp;
+#endif
+
+ if (iter->result6 != ISC_R_SUCCESS && iter->result6 != ISC_R_IGNORE)
+ return (iter->result6);
+
+ REQUIRE(iter->pos6 < (unsigned int) iter->lifc.lifc_len);
+
+#ifdef ISC_PLATFORM_HAVESALEN
+ ifrp = (struct LIFREQ *)((char *) iter->lifc.lifc_req + iter->pos6);
+
+ if (ifrp->lifr_addr.sa_len > sizeof(struct sockaddr))
+ iter->pos6 += sizeof(ifrp->lifr_name) + ifrp->lifr_addr.sa_len;
+ else
+#endif
+ iter->pos6 += sizeof(struct LIFREQ);
+
+ if (iter->pos6 >= (unsigned int) iter->lifc.lifc_len)
+ return (ISC_R_NOMORE);
+
+ return (ISC_R_SUCCESS);
+}
+#endif
+
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+#ifdef HAVE_TRUCLUSTER
+ int clua_result;
+#endif
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ if (iter->mode == 6) {
+ iter->result6 = internal_next6(iter);
+ if (iter->result6 != ISC_R_NOMORE)
+ return (iter->result6);
+ if (iter->first6) {
+ iter->first6 = ISC_FALSE;
+ return (ISC_R_SUCCESS);
+ }
+ }
+#endif
+#ifdef HAVE_TRUCLUSTER
+ if (!iter->clua_done) {
+ clua_result = clua_getaliasaddress(&iter->clua_sa,
+ &iter->clua_context);
+ if (clua_result != CLUA_SUCCESS)
+ iter->clua_done = ISC_TRUE;
+ return (ISC_R_SUCCESS);
+ }
+#endif
+ return (internal_next4(iter));
+}
+
+static void
+internal_destroy(isc_interfaceiter_t *iter) {
+ (void) close(iter->socket);
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ if (iter->socket6 != -1)
+ (void) close(iter->socket6);
+ if (iter->buf6 != NULL) {
+ isc_mem_put(iter->mctx, iter->buf6, iter->bufsize6);
+ }
+#endif
+#ifdef __linux
+ if (iter->proc != NULL)
+ fclose(iter->proc);
+#endif
+}
+
+static
+void internal_first(isc_interfaceiter_t *iter) {
+#ifdef HAVE_TRUCLUSTER
+ int clua_result;
+#endif
+ iter->pos = 0;
+#if defined(SIOCGLIFCONF) && defined(SIOCGLIFADDR)
+ iter->pos6 = 0;
+ if (iter->result6 == ISC_R_NOMORE)
+ iter->result6 = ISC_R_SUCCESS;
+ iter->first6 = ISC_TRUE;
+#endif
+#ifdef HAVE_TRUCLUSTER
+ iter->clua_context = 0;
+ clua_result = clua_getaliasaddress(&iter->clua_sa,
+ &iter->clua_context);
+ iter->clua_done = ISC_TF(clua_result != CLUA_SUCCESS);
+#endif
+#ifdef __linux
+ linux_if_inet6_first(iter);
+#endif
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/ifiter_sysctl.c b/contrib/ntp/libntp/lib/isc/unix/ifiter_sysctl.c
new file mode 100644
index 000000000000..0fbb3778e73a
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/ifiter_sysctl.c
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: ifiter_sysctl.c,v 1.25 2007/06/19 23:47:18 tbox Exp $ */
+
+/*! \file
+ * \brief
+ * Obtain the list of network interfaces using sysctl.
+ * See TCP/IP Illustrated Volume 2, sections 19.8, 19.14,
+ * and 19.16.
+ */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+
+#include <net/route.h>
+#include <net/if_dl.h>
+
+/* XXX what about Alpha? */
+#ifdef sgi
+#define ROUNDUP(a) ((a) > 0 ? \
+ (1 + (((a) - 1) | (sizeof(__uint64_t) - 1))) : \
+ sizeof(__uint64_t))
+#else
+#define ROUNDUP(a) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) \
+ : sizeof(long))
+#endif
+
+#define IFITER_MAGIC ISC_MAGIC('I', 'F', 'I', 'S')
+#define VALID_IFITER(t) ISC_MAGIC_VALID(t, IFITER_MAGIC)
+
+struct isc_interfaceiter {
+ unsigned int magic; /* Magic number. */
+ isc_mem_t *mctx;
+ void *buf; /* Buffer for sysctl data. */
+ unsigned int bufsize; /* Bytes allocated. */
+ unsigned int bufused; /* Bytes used. */
+ unsigned int pos; /* Current offset in
+ sysctl data. */
+ isc_interface_t current; /* Current interface data. */
+ isc_result_t result; /* Last result code. */
+};
+
+static int mib[6] = {
+ CTL_NET,
+ PF_ROUTE,
+ 0,
+ 0, /* Any address family. */
+ NET_RT_IFLIST,
+ 0 /* Flags. */
+};
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+ isc_interfaceiter_t *iter;
+ isc_result_t result;
+ size_t bufsize;
+ size_t bufused;
+ char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(iterp != NULL);
+ REQUIRE(*iterp == NULL);
+
+ iter = isc_mem_get(mctx, sizeof(*iter));
+ if (iter == NULL)
+ return (ISC_R_NOMEMORY);
+
+ iter->mctx = mctx;
+ iter->buf = 0;
+
+ /*
+ * Determine the amount of memory needed.
+ */
+ bufsize = 0;
+ if (sysctl(mib, 6, NULL, &bufsize, NULL, (size_t) 0) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERSYSCTL,
+ ISC_MSG_GETIFLISTSIZE,
+ "getting interface "
+ "list size: sysctl: %s"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto failure;
+ }
+ iter->bufsize = bufsize;
+
+ iter->buf = isc_mem_get(iter->mctx, iter->bufsize);
+ if (iter->buf == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto failure;
+ }
+
+ bufused = bufsize;
+ if (sysctl(mib, 6, iter->buf, &bufused, NULL, (size_t) 0) < 0) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERSYSCTL,
+ ISC_MSG_GETIFLIST,
+ "getting interface list: "
+ "sysctl: %s"),
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto failure;
+ }
+ iter->bufused = bufused;
+ INSIST(iter->bufused <= iter->bufsize);
+
+ /*
+ * A newly created iterator has an undefined position
+ * until isc_interfaceiter_first() is called.
+ */
+ iter->pos = (unsigned int) -1;
+ iter->result = ISC_R_FAILURE;
+
+ iter->magic = IFITER_MAGIC;
+ *iterp = iter;
+ return (ISC_R_SUCCESS);
+
+ failure:
+ if (iter->buf != NULL)
+ isc_mem_put(mctx, iter->buf, iter->bufsize);
+ isc_mem_put(mctx, iter, sizeof(*iter));
+ return (result);
+}
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family,
+ * return ISC_R_IGNORE. In case of other failure,
+ * return ISC_R_UNEXPECTED.
+ */
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+ struct ifa_msghdr *ifam, *ifam_end;
+
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE (iter->pos < (unsigned int) iter->bufused);
+
+ ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos);
+ ifam_end = (struct ifa_msghdr *) ((char *) iter->buf + iter->bufused);
+
+ // Skip wrong RTM version headers
+ if (ifam->ifam_version != RTM_VERSION)
+ return (ISC_R_IGNORE);
+
+ if (ifam->ifam_type == RTM_IFINFO) {
+ struct if_msghdr *ifm = (struct if_msghdr *) ifam;
+ struct sockaddr_dl *sdl = (struct sockaddr_dl *) (ifm + 1);
+ unsigned int namelen;
+
+ memset(&iter->current, 0, sizeof(iter->current));
+
+ iter->current.ifindex = sdl->sdl_index;
+ namelen = sdl->sdl_nlen;
+ if (namelen > sizeof(iter->current.name) - 1)
+ namelen = sizeof(iter->current.name) - 1;
+
+ memset(iter->current.name, 0, sizeof(iter->current.name));
+ memcpy(iter->current.name, sdl->sdl_data, namelen);
+
+ iter->current.flags = 0;
+
+ if ((ifam->ifam_flags & IFF_UP) != 0)
+ iter->current.flags |= INTERFACE_F_UP;
+
+ if ((ifam->ifam_flags & IFF_POINTOPOINT) != 0)
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+
+ if ((ifam->ifam_flags & IFF_LOOPBACK) != 0)
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+
+ if ((ifam->ifam_flags & IFF_BROADCAST) != 0)
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+
+#ifdef IFF_MULTICAST
+ if ((ifam->ifam_flags & IFF_MULTICAST) != 0)
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+#endif
+
+ /*
+ * This is not an interface address.
+ * Force another iteration.
+ */
+ return (ISC_R_IGNORE);
+ } else if (ifam->ifam_type == RTM_NEWADDR) {
+ int i;
+ int family;
+ struct sockaddr *mask_sa = NULL;
+ struct sockaddr *addr_sa = NULL;
+ struct sockaddr *dst_sa = NULL;
+
+ struct sockaddr *sa = (struct sockaddr *)(ifam + 1);
+ family = sa->sa_family;
+
+ for (i = 0; i < RTAX_MAX; i++)
+ {
+ if ((ifam->ifam_addrs & (1 << i)) == 0)
+ continue;
+
+ INSIST(sa < (struct sockaddr *) ifam_end);
+
+ switch (i) {
+ case RTAX_NETMASK: /* Netmask */
+ mask_sa = sa;
+ break;
+ case RTAX_IFA: /* Interface address */
+ addr_sa = sa;
+ break;
+ case RTAX_BRD: /* Broadcast or destination address */
+ dst_sa = sa;
+ break;
+ }
+#ifdef ISC_PLATFORM_HAVESALEN
+ sa = (struct sockaddr *)((char*)(sa)
+ + ROUNDUP(sa->sa_len));
+#else
+#ifdef sgi
+ /*
+ * Do as the contributed SGI code does.
+ */
+ sa = (struct sockaddr *)((char*)(sa)
+ + ROUNDUP(_FAKE_SA_LEN_DST(sa)));
+#else
+ /* XXX untested. */
+ sa = (struct sockaddr *)((char*)(sa)
+ + ROUNDUP(sizeof(struct sockaddr)));
+#endif
+#endif
+ }
+
+ if (addr_sa == NULL)
+ return (ISC_R_IGNORE);
+
+ family = addr_sa->sa_family;
+ if (family != AF_INET && family != AF_INET6)
+ return (ISC_R_IGNORE);
+
+ iter->current.af = family;
+
+ get_addr(family, &iter->current.address, addr_sa,
+ iter->current.name);
+
+ if (mask_sa != NULL)
+ get_addr(family, &iter->current.netmask, mask_sa,
+ iter->current.name);
+
+ if (dst_sa != NULL &&
+ (iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
+ get_addr(family, &iter->current.dstaddress, dst_sa,
+ iter->current.name);
+
+ if (dst_sa != NULL &&
+ (iter->current.flags & INTERFACE_F_BROADCAST) != 0)
+ get_addr(family, &iter->current.broadcast, dst_sa,
+ iter->current.name);
+
+ return (ISC_R_SUCCESS);
+ } else {
+ printf("%s", isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_IFITERSYSCTL,
+ ISC_MSG_UNEXPECTEDTYPE,
+ "warning: unexpected interface "
+ "list message type\n"));
+ return (ISC_R_IGNORE);
+ }
+}
+
+/*
+ * Step the iterator to the next interface. Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored. Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+ struct ifa_msghdr *ifam;
+ REQUIRE (iter->pos < (unsigned int) iter->bufused);
+
+ ifam = (struct ifa_msghdr *) ((char *) iter->buf + iter->pos);
+
+ iter->pos += ifam->ifam_msglen;
+
+ if (iter->pos >= iter->bufused)
+ return (ISC_R_NOMORE);
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+internal_destroy(isc_interfaceiter_t *iter) {
+ UNUSED(iter); /* Unused. */
+ /*
+ * Do nothing.
+ */
+}
+
+static
+void internal_first(isc_interfaceiter_t *iter) {
+ iter->pos = 0;
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/include/isc/dir.h b/contrib/ntp/libntp/lib/isc/unix/include/isc/dir.h
new file mode 100644
index 000000000000..e4a2ad0fb70d
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/include/isc/dir.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dir.h,v 1.21 2007/06/19 23:47:19 tbox Exp $ */
+
+/* Principal Authors: DCL */
+
+#ifndef ISC_DIR_H
+#define ISC_DIR_H 1
+
+/*! \file */
+
+#include <sys/types.h> /* Required on some systems. */
+#include <dirent.h>
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+#define ISC_DIR_NAMEMAX 256
+#define ISC_DIR_PATHMAX 1024
+
+/*% Directory Entry */
+typedef struct isc_direntry {
+ /*!
+ * Ideally, this should be NAME_MAX, but AIX does not define it by
+ * default and dynamically allocating the space based on pathconf()
+ * complicates things undesirably, as does adding special conditionals
+ * just for AIX. So a comfortably sized buffer is chosen instead.
+ */
+ char name[ISC_DIR_NAMEMAX];
+ unsigned int length;
+} isc_direntry_t;
+
+/*% Directory */
+typedef struct isc_dir {
+ unsigned int magic;
+ /*!
+ * As with isc_direntry_t->name, making this "right" for all systems
+ * is slightly problematic because AIX does not define PATH_MAX.
+ */
+ char dirname[ISC_DIR_PATHMAX];
+ isc_direntry_t entry;
+ DIR * handle;
+} isc_dir_t;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_dir_init(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_open(isc_dir_t *dir, const char *dirname);
+
+isc_result_t
+isc_dir_read(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_reset(isc_dir_t *dir);
+
+void
+isc_dir_close(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_chdir(const char *dirname);
+
+isc_result_t
+isc_dir_chroot(const char *dirname);
+
+isc_result_t
+isc_dir_createunique(char *templet);
+/*!<
+ * Use a templet (such as from isc_file_mktemplate()) to create a uniquely
+ * named, empty directory. The templet string is modified in place.
+ * If result == ISC_R_SUCCESS, it is the name of the directory that was
+ * created.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_DIR_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/include/isc/int.h b/contrib/ntp/libntp/lib/isc/unix/include/isc/int.h
new file mode 100644
index 000000000000..73feb3b65b3a
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/include/isc/int.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: int.h,v 1.16 2007/06/19 23:47:19 tbox Exp $ */
+
+#ifndef ISC_INT_H
+#define ISC_INT_H 1
+
+/*! \file */
+
+typedef char isc_int8_t;
+typedef unsigned char isc_uint8_t;
+typedef short isc_int16_t;
+typedef unsigned short isc_uint16_t;
+typedef int isc_int32_t;
+typedef unsigned int isc_uint32_t;
+typedef long long isc_int64_t;
+typedef unsigned long long isc_uint64_t;
+
+#define ISC_INT8_MIN -128
+#define ISC_INT8_MAX 127
+#define ISC_UINT8_MAX 255
+
+#define ISC_INT16_MIN -32768
+#define ISC_INT16_MAX 32767
+#define ISC_UINT16_MAX 65535
+
+/*%
+ * Note that "int" is 32 bits on all currently supported Unix-like operating
+ * systems, but "long" can be either 32 bits or 64 bits, thus the 32 bit
+ * constants are not qualified with "L".
+ */
+#define ISC_INT32_MIN -2147483648
+#define ISC_INT32_MAX 2147483647
+#define ISC_UINT32_MAX 4294967295U
+
+#define ISC_INT64_MIN -9223372036854775808LL
+#define ISC_INT64_MAX 9223372036854775807LL
+#define ISC_UINT64_MAX 18446744073709551615ULL
+
+#endif /* ISC_INT_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/include/isc/net.h b/contrib/ntp/libntp/lib/isc/unix/include/isc/net.h
new file mode 100644
index 000000000000..37a0f3b81fe8
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/include/isc/net.h
@@ -0,0 +1,364 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_NET_H
+#define ISC_NET_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \brief
+ * Basic Networking Types
+ *
+ * This module is responsible for defining the following basic networking
+ * types:
+ *
+ *\li struct in_addr
+ *\li struct in6_addr
+ *\li struct in6_pktinfo
+ *\li struct sockaddr
+ *\li struct sockaddr_in
+ *\li struct sockaddr_in6
+ *\li in_port_t
+ *
+ * It ensures that the AF_ and PF_ macros are defined.
+ *
+ * It declares ntoh[sl]() and hton[sl]().
+ *
+ * It declares inet_aton(), inet_ntop(), and inet_pton().
+ *
+ * It ensures that #INADDR_LOOPBACK, #INADDR_ANY, #IN6ADDR_ANY_INIT,
+ * in6addr_any, and in6addr_loopback are available.
+ *
+ * It ensures that IN_MULTICAST() is available to check for multicast
+ * addresses.
+ *
+ * MP:
+ *\li No impact.
+ *
+ * Reliability:
+ *\li No anticipated impact.
+ *
+ * Resources:
+ *\li N/A.
+ *
+ * Security:
+ *\li No anticipated impact.
+ *
+ * Standards:
+ *\li BSD Socket API
+ *\li RFC2553
+ */
+
+/***
+ *** Imports.
+ ***/
+#include <isc/platform.h>
+
+#include <sys/types.h>
+#include <sys/socket.h> /* Contractual promise. */
+
+#include <net/if.h>
+
+#include <netinet/in.h> /* Contractual promise. */
+#include <arpa/inet.h> /* Contractual promise. */
+#ifdef ISC_PLATFORM_NEEDNETINETIN6H
+#include <netinet/in6.h> /* Required on UnixWare. */
+#endif
+#ifdef ISC_PLATFORM_NEEDNETINET6IN6H
+#include <netinet6/in6.h> /* Required on BSD/OS for in6_pktinfo. */
+#endif
+
+#ifndef ISC_PLATFORM_HAVEIPV6
+#include <isc/ipv6.h> /* Contractual promise. */
+#endif
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#ifdef ISC_PLATFORM_HAVEINADDR6
+#define in6_addr in_addr6 /*%< Required for pre RFC2133 implementations. */
+#endif
+
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifndef IN6ADDR_ANY_INIT
+#ifdef s6_addr
+/*%
+ * Required for some pre RFC2133 implementations.
+ * IN6ADDR_ANY_INIT and IN6ADDR_LOOPBACK_INIT were added in
+ * draft-ietf-ipngwg-bsd-api-04.txt or draft-ietf-ipngwg-bsd-api-05.txt.
+ * If 's6_addr' is defined then assume that there is a union and three
+ * levels otherwise assume two levels required.
+ */
+#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
+#else
+#define IN6ADDR_ANY_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } }
+#endif
+#endif
+
+#ifndef IN6ADDR_LOOPBACK_INIT
+#ifdef s6_addr
+/*% IPv6 address loopback init */
+#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
+#else
+#define IN6ADDR_LOOPBACK_INIT { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } }
+#endif
+#endif
+
+#ifndef IN6_IS_ADDR_V4MAPPED
+/*% Is IPv6 address V4 mapped? */
+#define IN6_IS_ADDR_V4MAPPED(x) \
+ (memcmp((x)->s6_addr, in6addr_any.s6_addr, 10) == 0 && \
+ (x)->s6_addr[10] == 0xff && (x)->s6_addr[11] == 0xff)
+#endif
+
+#ifndef IN6_IS_ADDR_V4COMPAT
+/*% Is IPv6 address V4 compatible? */
+#define IN6_IS_ADDR_V4COMPAT(x) \
+ (memcmp((x)->s6_addr, in6addr_any.s6_addr, 12) == 0 && \
+ ((x)->s6_addr[12] != 0 || (x)->s6_addr[13] != 0 || \
+ (x)->s6_addr[14] != 0 || \
+ ((x)->s6_addr[15] != 0 && (x)->s6_addr[15] != 1)))
+#endif
+
+#ifndef IN6_IS_ADDR_MULTICAST
+/*% Is IPv6 address multicast? */
+#define IN6_IS_ADDR_MULTICAST(a) ((a)->s6_addr[0] == 0xff)
+#endif
+
+#ifndef IN6_IS_ADDR_LINKLOCAL
+/*% Is IPv6 address linklocal? */
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+#endif
+
+#ifndef IN6_IS_ADDR_SITELOCAL
+/*% is IPv6 address sitelocal? */
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+#endif
+
+
+#ifndef IN6_IS_ADDR_LOOPBACK
+/*% is IPv6 address loopback? */
+#define IN6_IS_ADDR_LOOPBACK(x) \
+ (memcmp((x)->s6_addr, in6addr_loopback.s6_addr, 16) == 0)
+#endif
+#endif
+
+#ifndef AF_INET6
+/*% IPv6 */
+#define AF_INET6 99
+#endif
+
+#ifndef PF_INET6
+/*% IPv6 */
+#define PF_INET6 AF_INET6
+#endif
+
+#ifndef INADDR_LOOPBACK
+/*% inaddr loopback */
+#define INADDR_LOOPBACK 0x7f000001UL
+#endif
+
+#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
+/*% IPv6 packet info */
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr; /*%< src/dst IPv6 address */
+ unsigned int ipi6_ifindex; /*%< send/recv interface index */
+};
+#endif
+
+#if defined(ISC_PLATFORM_NEEDIN6ADDRANY)
+extern const struct in6_addr isc_net_in6addrany;
+/*%
+ * Cope with a missing in6addr_any and in6addr_loopback.
+ */
+#define in6addr_any isc_net_in6addrany
+#endif
+
+#if defined(ISC_PLATFORM_HAVEIPV6) && defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
+extern const struct in6_addr isc_net_in6addrloop;
+#define in6addr_loopback isc_net_in6addrloop
+#endif
+
+#ifdef ISC_PLATFORM_FIXIN6ISADDR
+#undef IN6_IS_ADDR_GEOGRAPHIC
+/*!
+ * \brief
+ * Fix UnixWare 7.1.1's broken IN6_IS_ADDR_* definitions.
+ */
+#define IN6_IS_ADDR_GEOGRAPHIC(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x80)
+#undef IN6_IS_ADDR_IPX
+#define IN6_IS_ADDR_IPX(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x04)
+#undef IN6_IS_ADDR_LINKLOCAL
+#define IN6_IS_ADDR_LINKLOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0x80FE)
+#undef IN6_IS_ADDR_MULTICAST
+#define IN6_IS_ADDR_MULTICAST(a) (((a)->S6_un.S6_l[0] & 0xFF) == 0xFF)
+#undef IN6_IS_ADDR_NSAP
+#define IN6_IS_ADDR_NSAP(a) (((a)->S6_un.S6_l[0] & 0xFE) == 0x02)
+#undef IN6_IS_ADDR_PROVIDER
+#define IN6_IS_ADDR_PROVIDER(a) (((a)->S6_un.S6_l[0] & 0xE0) == 0x40)
+#undef IN6_IS_ADDR_SITELOCAL
+#define IN6_IS_ADDR_SITELOCAL(a) (((a)->S6_un.S6_l[0] & 0xC0FF) == 0xC0FE)
+#endif /* ISC_PLATFORM_FIXIN6ISADDR */
+
+#ifdef ISC_PLATFORM_NEEDPORTT
+/*%
+ * Ensure type in_port_t is defined.
+ */
+typedef isc_uint16_t in_port_t;
+#endif
+
+#ifndef MSG_TRUNC
+/*%
+ * If this system does not have MSG_TRUNC (as returned from recvmsg())
+ * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC
+ * faking code in socket.c.
+ */
+#define ISC_PLATFORM_RECVOVERFLOW
+#endif
+
+/*% IP address. */
+#define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x)))
+
+/*% Is IP address multicast? */
+#define ISC_IPADDR_ISMULTICAST(i) \
+ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
+ == ISC__IPADDR(0xe0000000))
+
+#define ISC_IPADDR_ISEXPERIMENTAL(i) \
+ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
+ == ISC__IPADDR(0xf0000000))
+
+/***
+ *** Functions.
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_net_probeipv4(void);
+/*%<
+ * Check if the system's kernel supports IPv4.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS IPv4 is supported.
+ *\li #ISC_R_NOTFOUND IPv4 is not supported.
+ *\li #ISC_R_DISABLED IPv4 is disabled.
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probeipv6(void);
+/*%<
+ * Check if the system's kernel supports IPv6.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS IPv6 is supported.
+ *\li #ISC_R_NOTFOUND IPv6 is not supported.
+ *\li #ISC_R_DISABLED IPv6 is disabled.
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probe_ipv6only(void);
+/*%<
+ * Check if the system's kernel supports the IPV6_V6ONLY socket option.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS the option is supported for both TCP and UDP.
+ *\li #ISC_R_NOTFOUND IPv6 itself or the option is not supported.
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probe_ipv6pktinfo(void);
+/*
+ * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
+ * for UDP sockets.
+ *
+ * Returns:
+ *
+ * \li #ISC_R_SUCCESS the option is supported.
+ * \li #ISC_R_NOTFOUND IPv6 itself or the option is not supported.
+ * \li #ISC_R_UNEXPECTED
+ */
+
+void
+isc_net_disableipv4(void);
+
+void
+isc_net_disableipv6(void);
+
+void
+isc_net_enableipv4(void);
+
+void
+isc_net_enableipv6(void);
+
+isc_result_t
+isc_net_probeunix(void);
+/*
+ * Returns whether UNIX domain sockets are supported.
+ */
+
+isc_result_t
+isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
+/*%<
+ * Returns system's default range of ephemeral UDP ports, if defined.
+ * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
+ * ISC_NET_PORTRANGEHIGH will be returned.
+ *
+ * Requires:
+ *
+ *\li 'low' and 'high' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li *low and *high will be the ports specifying the low and high ends of
+ * the range.
+ */
+
+#ifdef ISC_PLATFORM_NEEDNTOP
+const char *
+isc_net_ntop(int af, const void *src, char *dst, size_t size);
+#define inet_ntop isc_net_ntop
+#endif
+
+#ifdef ISC_PLATFORM_NEEDPTON
+int
+isc_net_pton(int af, const char *src, void *dst);
+#undef inet_pton
+#define inet_pton isc_net_pton
+#endif
+
+int
+isc_net_aton(const char *cp, struct in_addr *addr);
+#undef inet_aton
+#define inet_aton isc_net_aton
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NET_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/include/isc/offset.h b/contrib/ntp/libntp/lib/isc/unix/include/isc/offset.h
new file mode 100644
index 000000000000..8bf3779997cd
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/include/isc/offset.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: offset.h,v 1.17 2008/12/01 23:47:45 tbox Exp $ */
+
+#ifndef ISC_OFFSET_H
+#define ISC_OFFSET_H 1
+
+/*! \file
+ * \brief
+ * File offsets are operating-system dependent.
+ */
+#include <limits.h> /* Required for CHAR_BIT. */
+#include <sys/types.h>
+#include <stddef.h> /* For Linux Standard Base. */
+
+typedef off_t isc_offset_t;
+
+/*%
+ * POSIX says "Additionally, blkcnt_t and off_t are extended signed integral
+ * types", so the maximum value is all 1s except for the high bit.
+ * This definition is more complex than it really needs to be because it was
+ * crafted to keep both the SunOS 5.6 and the HP/UX 11 compilers quiet about
+ * integer overflow. For example, though this is equivalent to just left
+ * shifting 1 to the high bit and then inverting the bits, the SunOS compiler
+ * is unhappy about shifting a positive "1" to negative in a signed integer.
+ */
+#define ISC_OFFSET_MAXIMUM \
+ (~(((off_t)-1 >> (sizeof(off_t) * CHAR_BIT - 1)) \
+ << (sizeof(off_t) * CHAR_BIT - 1)))
+
+#endif /* ISC_OFFSET_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/include/isc/stat.h b/contrib/ntp/libntp/lib/isc/unix/include/isc/stat.h
new file mode 100644
index 000000000000..b7a798649225
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/include/isc/stat.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: stat.h,v 1.5 2007/06/19 23:47:19 tbox Exp $ */
+
+#ifndef ISC_STAT_H
+#define ISC_STAT_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * Portable netdb.h support.
+ *
+ * This module is responsible for defining S_IS??? macros.
+ *
+ * MP:
+ * No impact.
+ *
+ * Reliability:
+ * No anticipated impact.
+ *
+ * Resources:
+ * N/A.
+ *
+ * Security:
+ * No anticipated impact.
+ *
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#endif /* ISC_STAT_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/include/isc/stdtime.h b/contrib/ntp/libntp/lib/isc/unix/include/isc/stdtime.h
new file mode 100644
index 000000000000..c4931bfe6362
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/include/isc/stdtime.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_STDTIME_H
+#define ISC_STDTIME_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/int.h>
+
+/*%
+ * It's public information that 'isc_stdtime_t' is an unsigned integral type.
+ * Applications that want maximum portability should not assume anything
+ * about its size.
+ */
+typedef isc_uint32_t isc_stdtime_t;
+
+/* but this flag helps... */
+#define STDTIME_ON_32BITS 1
+
+/*
+ * isc_stdtime32_t is a 32-bit version of isc_stdtime_t. A variable of this
+ * type should only be used as an opaque integer (e.g.,) to compare two
+ * time values.
+ */
+typedef isc_uint32_t isc_stdtime32_t;
+
+ISC_LANG_BEGINDECLS
+/* */
+void
+isc_stdtime_get(isc_stdtime_t *t);
+/*%<
+ * Set 't' to the number of seconds since 00:00:00 UTC, January 1, 1970.
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ */
+
+#define isc_stdtime_convert32(t, t32p) (*(t32p) = t)
+/*
+ * Convert the standard time to its 32-bit version.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STDTIME_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/include/isc/strerror.h b/contrib/ntp/libntp/lib/isc/unix/include/isc/strerror.h
new file mode 100644
index 000000000000..899043bbffdd
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/include/isc/strerror.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: strerror.h,v 1.10 2008/12/01 23:47:45 tbox Exp $ */
+
+#ifndef ISC_STRERROR_H
+#define ISC_STRERROR_H
+
+/*! \file */
+
+#include <sys/types.h>
+
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+/*% String Error Size */
+#define ISC_STRERRORSIZE 128
+
+/*%
+ * Provide a thread safe wrapper to strerror().
+ *
+ * Requires:
+ * 'buf' to be non NULL.
+ */
+void
+isc__strerror(int num, char *buf, size_t bufsize);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STRERROR_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/include/isc/time.h b/contrib/ntp/libntp/lib/isc/unix/include/isc/time.h
new file mode 100644
index 000000000000..dc1cef9ad3f2
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/include/isc/time.h
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2004-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: time.h,v 1.40 2009/01/05 23:47:54 tbox Exp $ */
+
+#ifndef ISC_TIME_H
+#define ISC_TIME_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/***
+ *** Intervals
+ ***/
+
+/*!
+ * \brief
+ * The contents of this structure are private, and MUST NOT be accessed
+ * directly by callers.
+ *
+ * The contents are exposed only to allow callers to avoid dynamic allocation.
+ */
+struct isc_interval {
+ unsigned int seconds;
+ unsigned int nanoseconds;
+};
+
+extern isc_interval_t *isc_interval_zero;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_interval_set(isc_interval_t *i,
+ unsigned int seconds, unsigned int nanoseconds);
+/*%<
+ * Set 'i' to a value representing an interval of 'seconds' seconds and
+ * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and
+ * isc_time_subtract().
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ *\li nanoseconds < 1000000000.
+ */
+
+isc_boolean_t
+isc_interval_iszero(const isc_interval_t *i);
+/*%<
+ * Returns ISC_TRUE iff. 'i' is the zero interval.
+ *
+ * Requires:
+ *
+ *\li 'i' is a valid pointer.
+ */
+
+/***
+ *** Absolute Times
+ ***/
+
+/*%
+ * The contents of this structure are private, and MUST NOT be accessed
+ * directly by callers.
+ *
+ * The contents are exposed only to allow callers to avoid dynamic allocation.
+ */
+
+struct isc_time {
+ unsigned int seconds;
+ unsigned int nanoseconds;
+};
+
+extern isc_time_t *isc_time_epoch;
+
+void
+isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds);
+/*%<
+ * Set 't' to a value which represents the given number of seconds and
+ * nanoseconds since 00:00:00 January 1, 1970, UTC.
+ *
+ * Notes:
+ *\li The Unix version of this call is equivalent to:
+ *\code
+ * isc_time_settoepoch(t);
+ * isc_interval_set(i, seconds, nanoseconds);
+ * isc_time_add(t, i, t);
+ *\endcode
+ *
+ * Requires:
+ *\li 't' is a valid pointer.
+ *\li nanoseconds < 1000000000.
+ */
+
+void
+isc_time_settoepoch(isc_time_t *t);
+/*%<
+ * Set 't' to the time of the epoch.
+ *
+ * Notes:
+ *\li The date of the epoch is platform-dependent.
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ */
+
+isc_boolean_t
+isc_time_isepoch(const isc_time_t *t);
+/*%<
+ * Returns ISC_TRUE iff. 't' is the epoch ("time zero").
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ */
+
+isc_result_t
+isc_time_now(isc_time_t *t);
+/*%<
+ * Set 't' to the current absolute time.
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li Unexpected error
+ * Getting the time from the system failed.
+ *\li Out of range
+ * The time from the system is too large to be represented
+ * in the current definition of isc_time_t.
+ */
+
+isc_result_t
+isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
+/*%<
+ * Set *t to the current absolute time + i.
+ *
+ * Note:
+ *\li This call is equivalent to:
+ *
+ *\code
+ * isc_time_now(t);
+ * isc_time_add(t, i, t);
+ *\endcode
+ *
+ * Requires:
+ *
+ *\li 't' and 'i' are valid pointers.
+ *
+ * Returns:
+ *
+ *\li Success
+ *\li Unexpected error
+ * Getting the time from the system failed.
+ *\li Out of range
+ * The interval added to the time from the system is too large to
+ * be represented in the current definition of isc_time_t.
+ */
+
+int
+isc_time_compare(const isc_time_t *t1, const isc_time_t *t2);
+/*%<
+ * Compare the times referenced by 't1' and 't2'
+ *
+ * Requires:
+ *
+ *\li 't1' and 't2' are valid pointers.
+ *
+ * Returns:
+ *
+ *\li -1 t1 < t2 (comparing times, not pointers)
+ *\li 0 t1 = t2
+ *\li 1 t1 > t2
+ */
+
+isc_result_t
+isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result);
+/*%<
+ * Add 'i' to 't', storing the result in 'result'.
+ *
+ * Requires:
+ *
+ *\li 't', 'i', and 'result' are valid pointers.
+ *
+ * Returns:
+ *\li Success
+ *\li Out of range
+ * The interval added to the time is too large to
+ * be represented in the current definition of isc_time_t.
+ */
+
+isc_result_t
+isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
+ isc_time_t *result);
+/*%<
+ * Subtract 'i' from 't', storing the result in 'result'.
+ *
+ * Requires:
+ *
+ *\li 't', 'i', and 'result' are valid pointers.
+ *
+ * Returns:
+ *\li Success
+ *\li Out of range
+ * The interval is larger than the time since the epoch.
+ */
+
+isc_uint64_t
+isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2);
+/*%<
+ * Find the difference in microseconds between time t1 and time t2.
+ * t2 is the subtrahend of t1; ie, difference = t1 - t2.
+ *
+ * Requires:
+ *
+ *\li 't1' and 't2' are valid pointers.
+ *
+ * Returns:
+ *\li The difference of t1 - t2, or 0 if t1 <= t2.
+ */
+
+isc_uint32_t
+isc_time_seconds(const isc_time_t *t);
+/*%<
+ * Return the number of seconds since the epoch stored in a time structure.
+ *
+ * Requires:
+ *
+ *\li 't' is a valid pointer.
+ */
+
+isc_result_t
+isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp);
+/*%<
+ * Ensure the number of seconds in an isc_time_t is representable by a time_t.
+ *
+ * Notes:
+ *\li The number of seconds stored in an isc_time_t might be larger
+ * than the number of seconds a time_t is able to handle. Since
+ * time_t is mostly opaque according to the ANSI/ISO standard
+ * (essentially, all you can be sure of is that it is an arithmetic type,
+ * not even necessarily integral), it can be tricky to ensure that
+ * the isc_time_t is in the range a time_t can handle. Use this
+ * function in place of isc_time_seconds() any time you need to set a
+ * time_t from an isc_time_t.
+ *
+ * Requires:
+ *\li 't' is a valid pointer.
+ *
+ * Returns:
+ *\li Success
+ *\li Out of range
+ */
+
+isc_uint32_t
+isc_time_nanoseconds(const isc_time_t *t);
+/*%<
+ * Return the number of nanoseconds stored in a time structure.
+ *
+ * Notes:
+ *\li This is the number of nanoseconds in excess of the number
+ * of seconds since the epoch; it will always be less than one
+ * full second.
+ *
+ * Requires:
+ *\li 't' is a valid pointer.
+ *
+ * Ensures:
+ *\li The returned value is less than 1*10^9.
+ */
+
+void
+isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len);
+/*%<
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using a format like "30-Aug-2000 04:06:47.997" and the local time zone.
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ *\li 'len' > 0
+ *\li 'buf' points to an array of at least len chars
+ *
+ */
+
+void
+isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len);
+/*%<
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using a format like "Mon, 30 Aug 2000 04:06:47 GMT"
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ *\li 'len' > 0
+ *\li 'buf' points to an array of at least len chars
+ *
+ */
+
+void
+isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len);
+/*%<
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ"
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ *\li 'len' > 0
+ *\li 'buf' points to an array of at least len chars
+ *
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TIME_H */
diff --git a/contrib/ntp/libntp/lib/isc/unix/interfaceiter.c b/contrib/ntp/libntp/lib/isc/unix/interfaceiter.c
new file mode 100644
index 000000000000..c42fa685c920
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/interfaceiter.c
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: interfaceiter.c,v 1.45 2008/12/01 03:51:47 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#ifdef HAVE_SYS_SOCKIO_H
+#include <sys/sockio.h> /* Required for ifiter_ioctl.c. */
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <isc/interfaceiter.h>
+#include <isc/log.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/net.h>
+#include <isc/print.h>
+#include <isc/result.h>
+#include <isc/strerror.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+/* Must follow <isc/net.h>. */
+#ifdef HAVE_NET_IF6_H
+#include <net/if6.h>
+#endif
+#include <net/if.h>
+
+#ifdef HAVE_LINUX_IF_ADDR_H
+# include <linux/if_addr.h>
+#endif
+
+/* Common utility functions */
+
+/*%
+ * Extract the network address part from a "struct sockaddr".
+ * \brief
+ * The address family is given explicitly
+ * instead of using src->sa_family, because the latter does not work
+ * for copying a network mask obtained by SIOCGIFNETMASK (it does
+ * not have a valid address family).
+ */
+
+static void
+get_addr(unsigned int family, isc_netaddr_t *dst, struct sockaddr *src,
+ char *ifname)
+{
+ struct sockaddr_in6 *sa6;
+
+#if !defined(ISC_PLATFORM_HAVEIFNAMETOINDEX) || \
+ !defined(ISC_PLATFORM_HAVESCOPEID)
+ UNUSED(ifname);
+#endif
+
+ /* clear any remaining value for safety */
+ memset(dst, 0, sizeof(*dst));
+
+ dst->family = family;
+ switch (family) {
+ case AF_INET:
+ memcpy(&dst->type.in,
+ &((struct sockaddr_in *)(void *)src)->sin_addr,
+ sizeof(struct in_addr));
+ break;
+ case AF_INET6:
+ sa6 = (struct sockaddr_in6 *)(void *)src;
+ memcpy(&dst->type.in6, &sa6->sin6_addr,
+ sizeof(struct in6_addr));
+#ifdef ISC_PLATFORM_HAVESCOPEID
+ if (sa6->sin6_scope_id != 0)
+ isc_netaddr_setzone(dst, sa6->sin6_scope_id);
+ else {
+ /*
+ * BSD variants embed scope zone IDs in the 128bit
+ * address as a kernel internal form. Unfortunately,
+ * the embedded IDs are not hidden from applications
+ * when getting access to them by sysctl or ioctl.
+ * We convert the internal format to the pure address
+ * part and the zone ID part.
+ * Since multicast addresses should not appear here
+ * and they cannot be distinguished from netmasks,
+ * we only consider unicast link-local addresses.
+ */
+ if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
+ isc_uint16_t zone16;
+
+ memcpy(&zone16, &sa6->sin6_addr.s6_addr[2],
+ sizeof(zone16));
+ zone16 = ntohs(zone16);
+ if (zone16 != 0) {
+ /* the zone ID is embedded */
+ isc_netaddr_setzone(dst,
+ (isc_uint32_t)zone16);
+ dst->type.in6.s6_addr[2] = 0;
+ dst->type.in6.s6_addr[3] = 0;
+#ifdef ISC_PLATFORM_HAVEIFNAMETOINDEX
+ } else if (ifname != NULL) {
+ unsigned int zone;
+
+ /*
+ * sin6_scope_id is still not provided,
+ * but the corresponding interface name
+ * is know. Use the interface ID as
+ * the link ID.
+ */
+ zone = if_nametoindex(ifname);
+ if (zone != 0) {
+ isc_netaddr_setzone(dst,
+ (isc_uint32_t)zone);
+ }
+#endif
+ }
+ }
+ }
+#endif
+ break;
+ default:
+ INSIST(0);
+ break;
+ }
+}
+
+/*
+ * Include system-dependent code.
+ */
+
+#ifdef __linux
+#define ISC_IF_INET6_SZ \
+ sizeof("00000000000000000000000000000001 01 80 10 80 XXXXXXloXXXXXXXX\n")
+static isc_result_t linux_if_inet6_next(isc_interfaceiter_t *);
+static isc_result_t linux_if_inet6_current(isc_interfaceiter_t *);
+static void linux_if_inet6_first(isc_interfaceiter_t *iter);
+#endif
+
+#if HAVE_GETIFADDRS
+#include "ifiter_getifaddrs.c"
+#elif HAVE_IFLIST_SYSCTL
+#include "ifiter_sysctl.c"
+#else
+#include "ifiter_ioctl.c"
+#endif
+
+#ifdef __linux
+static void
+linux_if_inet6_first(isc_interfaceiter_t *iter) {
+ if (iter->proc != NULL) {
+ rewind(iter->proc);
+ (void)linux_if_inet6_next(iter);
+ } else
+ iter->valid = ISC_R_NOMORE;
+}
+
+static isc_result_t
+linux_if_inet6_next(isc_interfaceiter_t *iter) {
+ if (iter->proc != NULL &&
+ fgets(iter->entry, sizeof(iter->entry), iter->proc) != NULL)
+ iter->valid = ISC_R_SUCCESS;
+ else
+ iter->valid = ISC_R_NOMORE;
+ return (iter->valid);
+}
+
+static isc_result_t
+linux_if_inet6_current(isc_interfaceiter_t *iter) {
+ char address[33];
+ char name[IF_NAMESIZE+1];
+ struct in6_addr addr6;
+ unsigned int ifindex;
+ int prefix, scope, flags;
+ int res;
+ unsigned int i;
+
+ if (iter->valid != ISC_R_SUCCESS)
+ return (iter->valid);
+ if (iter->proc == NULL) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:iter->proc == NULL");
+ return (ISC_R_FAILURE);
+ }
+
+ res = sscanf(iter->entry, "%32[a-f0-9] %x %x %x %x %16s\n",
+ address, &ifindex, &prefix, &scope, &flags, name);
+ if (res != 6) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:sscanf() -> %d (expected 6)",
+ res);
+ return (ISC_R_FAILURE);
+ }
+ if (strlen(address) != 32) {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_INTERFACE, ISC_LOG_ERROR,
+ "/proc/net/if_inet6:strlen(%s) != 32", address);
+ return (ISC_R_FAILURE);
+ }
+ /*
+ ** Ignore DAD addresses --
+ ** we can't bind to them until they are resolved
+ */
+#ifdef IFA_F_TENTATIVE
+ if (flags & IFA_F_TENTATIVE)
+ return (ISC_R_IGNORE);
+#endif
+
+ for (i = 0; i < 16; i++) {
+ unsigned char byte;
+ static const char hex[] = "0123456789abcdef";
+ byte = ((strchr(hex, address[i * 2]) - hex) << 4) |
+ (strchr(hex, address[i * 2 + 1]) - hex);
+ addr6.s6_addr[i] = byte;
+ }
+ iter->current.af = AF_INET6;
+ iter->current.flags = INTERFACE_F_UP;
+ isc_netaddr_fromin6(&iter->current.address, &addr6);
+ iter->current.ifindex = ifindex;
+ if (isc_netaddr_islinklocal(&iter->current.address)) {
+ isc_netaddr_setzone(&iter->current.address,
+ (isc_uint32_t)ifindex);
+ }
+ for (i = 0; i < 16; i++) {
+ if (prefix > 8) {
+ addr6.s6_addr[i] = 0xff;
+ prefix -= 8;
+ } else {
+ addr6.s6_addr[i] = (0xff << (8 - prefix)) & 0xff;
+ prefix = 0;
+ }
+ }
+ isc_netaddr_fromin6(&iter->current.netmask, &addr6);
+ strncpy(iter->current.name, name, sizeof(iter->current.name));
+ return (ISC_R_SUCCESS);
+}
+#endif
+
+/*
+ * The remaining code is common to the sysctl and ioctl case.
+ */
+
+isc_result_t
+isc_interfaceiter_current(isc_interfaceiter_t *iter,
+ isc_interface_t *ifdata)
+{
+ REQUIRE(iter->result == ISC_R_SUCCESS);
+ memcpy(ifdata, &iter->current, sizeof(*ifdata));
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_interfaceiter_first(isc_interfaceiter_t *iter) {
+ isc_result_t result;
+
+ REQUIRE(VALID_IFITER(iter));
+
+ internal_first(iter);
+ for (;;) {
+ result = internal_current(iter);
+ if (result != ISC_R_IGNORE)
+ break;
+ result = internal_next(iter);
+ if (result != ISC_R_SUCCESS)
+ break;
+ }
+ iter->result = result;
+ return (result);
+}
+
+isc_result_t
+isc_interfaceiter_next(isc_interfaceiter_t *iter) {
+ isc_result_t result;
+
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(iter->result == ISC_R_SUCCESS);
+
+ for (;;) {
+ result = internal_next(iter);
+ if (result != ISC_R_SUCCESS)
+ break;
+ result = internal_current(iter);
+ if (result != ISC_R_IGNORE)
+ break;
+ }
+ iter->result = result;
+ return (result);
+}
+
+void
+isc_interfaceiter_destroy(isc_interfaceiter_t **iterp)
+{
+ isc_interfaceiter_t *iter;
+ REQUIRE(iterp != NULL);
+ iter = *iterp;
+ REQUIRE(VALID_IFITER(iter));
+
+ internal_destroy(iter);
+ if (iter->buf != NULL)
+ isc_mem_put(iter->mctx, iter->buf, iter->bufsize);
+
+ iter->magic = 0;
+ isc_mem_put(iter->mctx, iter, sizeof(*iter));
+ *iterp = NULL;
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/net.c b/contrib/ntp/libntp/lib/isc/unix/net.c
new file mode 100644
index 000000000000..7056668ca0cd
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/net.c
@@ -0,0 +1,523 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include <config.h>
+
+#include <sys/types.h>
+
+#if defined(HAVE_SYS_SYSCTL_H)
+#if defined(HAVE_SYS_PARAM_H)
+#include <sys/param.h>
+#endif
+#include <sys/sysctl.h>
+#endif
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <isc/log.h>
+#include <isc/msgs.h>
+#include <isc/net.h>
+#include <isc/once.h>
+#include <isc/strerror.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+/*%
+ * Definitions about UDP port range specification. This is a total mess of
+ * portability variants: some use sysctl (but the sysctl names vary), some use
+ * system-specific interfaces, some have the same interface for IPv4 and IPv6,
+ * some separate them, etc...
+ */
+
+/*%
+ * The last resort defaults: use all non well known port space
+ */
+#ifndef ISC_NET_PORTRANGELOW
+#define ISC_NET_PORTRANGELOW 1024
+#endif /* ISC_NET_PORTRANGELOW */
+#ifndef ISC_NET_PORTRANGEHIGH
+#define ISC_NET_PORTRANGEHIGH 65535
+#endif /* ISC_NET_PORTRANGEHIGH */
+
+#ifdef HAVE_SYSCTLBYNAME
+
+/*%
+ * sysctl variants
+ */
+#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__)
+#define USE_SYSCTL_PORTRANGE
+#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.portrange.hifirst"
+#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.portrange.hilast"
+#define SYSCTL_V6PORTRANGE_LOW "net.inet.ip.portrange.hifirst"
+#define SYSCTL_V6PORTRANGE_HIGH "net.inet.ip.portrange.hilast"
+#endif
+
+#ifdef __NetBSD__
+#define USE_SYSCTL_PORTRANGE
+#define SYSCTL_V4PORTRANGE_LOW "net.inet.ip.anonportmin"
+#define SYSCTL_V4PORTRANGE_HIGH "net.inet.ip.anonportmax"
+#define SYSCTL_V6PORTRANGE_LOW "net.inet6.ip6.anonportmin"
+#define SYSCTL_V6PORTRANGE_HIGH "net.inet6.ip6.anonportmax"
+#endif
+
+#else /* !HAVE_SYSCTLBYNAME */
+
+#ifdef __OpenBSD__
+#define USE_SYSCTL_PORTRANGE
+#define SYSCTL_V4PORTRANGE_LOW { CTL_NET, PF_INET, IPPROTO_IP, \
+ IPCTL_IPPORT_HIFIRSTAUTO }
+#define SYSCTL_V4PORTRANGE_HIGH { CTL_NET, PF_INET, IPPROTO_IP, \
+ IPCTL_IPPORT_HILASTAUTO }
+/* Same for IPv6 */
+#define SYSCTL_V6PORTRANGE_LOW SYSCTL_V4PORTRANGE_LOW
+#define SYSCTL_V6PORTRANGE_HIGH SYSCTL_V4PORTRANGE_HIGH
+#endif
+
+#endif /* HAVE_SYSCTLBYNAME */
+
+#if defined(ISC_PLATFORM_NEEDIN6ADDRANY)
+const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
+#endif
+
+#if defined(ISC_PLATFORM_HAVEIPV6)
+
+# if defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
+const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT;
+# endif
+
+# if defined(WANT_IPV6)
+static isc_once_t once_ipv6only = ISC_ONCE_INIT;
+# endif
+
+# if defined(ISC_PLATFORM_HAVEIPV6) && \
+ defined(WANT_IPV6) && defined(ISC_PLATFORM_HAVEIN6PKTINFO)
+static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT;
+# endif
+#endif /* ISC_PLATFORM_HAVEIPV6 */
+
+static isc_once_t once = ISC_ONCE_INIT;
+
+static isc_result_t ipv4_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6_result = ISC_R_NOTFOUND;
+static isc_result_t unix_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6only_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND;
+
+static isc_result_t
+try_proto(int domain) {
+ int s;
+ isc_result_t result = ISC_R_SUCCESS;
+ char strbuf[ISC_STRERRORSIZE];
+
+ s = socket(domain, SOCK_STREAM, 0);
+ if (s == -1) {
+ switch (errno) {
+#ifdef EAFNOSUPPORT
+ case EAFNOSUPPORT:
+#endif
+#ifdef EPROTONOSUPPORT
+ case EPROTONOSUPPORT:
+#endif
+#ifdef EINVAL
+ case EINVAL:
+#endif
+ return (ISC_R_NOTFOUND);
+ default:
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+ }
+
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+ if (domain == PF_INET6) {
+ struct sockaddr_in6 sin6;
+ GETSOCKNAME_SOCKLEN_TYPE len; /* NTP local change */
+
+ /*
+ * Check to see if IPv6 is broken, as is common on Linux.
+ */
+ len = sizeof(sin6);
+ if (getsockname(s, (struct sockaddr *)&sin6, &len) < 0)
+ {
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "retrieving the address of an IPv6 "
+ "socket from the kernel failed.");
+ isc_log_write(isc_lctx, ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET, ISC_LOG_ERROR,
+ "IPv6 is not supported.");
+ result = ISC_R_NOTFOUND;
+ } else {
+ if (len == sizeof(struct sockaddr_in6))
+ result = ISC_R_SUCCESS;
+ else {
+ isc_log_write(isc_lctx,
+ ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET,
+ ISC_LOG_ERROR,
+ "IPv6 structures in kernel and "
+ "user space do not match.");
+ isc_log_write(isc_lctx,
+ ISC_LOGCATEGORY_GENERAL,
+ ISC_LOGMODULE_SOCKET,
+ ISC_LOG_ERROR,
+ "IPv6 is not supported.");
+ result = ISC_R_NOTFOUND;
+ }
+ }
+ }
+#endif
+#endif
+#endif
+
+ (void)close(s);
+
+ return (result);
+}
+
+static void
+initialize_action(void) {
+ ipv4_result = try_proto(PF_INET);
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+ ipv6_result = try_proto(PF_INET6);
+#endif
+#endif
+#endif
+#ifdef ISC_PLATFORM_HAVESYSUNH
+ unix_result = try_proto(PF_UNIX);
+#endif
+}
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_net_probeipv4(void) {
+ initialize();
+ return (ipv4_result);
+}
+
+isc_result_t
+isc_net_probeipv6(void) {
+ initialize();
+ return (ipv6_result);
+}
+
+isc_result_t
+isc_net_probeunix(void) {
+ initialize();
+ return (unix_result);
+}
+
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+static void
+try_ipv6only(void) {
+#ifdef IPV6_V6ONLY
+ int s, on;
+ char strbuf[ISC_STRERRORSIZE];
+#endif
+ isc_result_t result;
+
+ result = isc_net_probeipv6();
+ if (result != ISC_R_SUCCESS) {
+ ipv6only_result = result;
+ return;
+ }
+
+#ifndef IPV6_V6ONLY
+ ipv6only_result = ISC_R_NOTFOUND;
+ return;
+#else
+ /* check for TCP sockets */
+ s = socket(PF_INET6, SOCK_STREAM, 0);
+ if (s == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6only_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
+ ipv6only_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ close(s);
+
+ /* check for UDP sockets */
+ s = socket(PF_INET6, SOCK_DGRAM, 0);
+ if (s == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6only_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) < 0) {
+ ipv6only_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ ipv6only_result = ISC_R_SUCCESS;
+
+close:
+ close(s);
+ return;
+#endif /* IPV6_V6ONLY */
+}
+
+static void
+initialize_ipv6only(void) {
+ RUNTIME_CHECK(isc_once_do(&once_ipv6only,
+ try_ipv6only) == ISC_R_SUCCESS);
+}
+
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+static void
+try_ipv6pktinfo(void) {
+ int s, on;
+ char strbuf[ISC_STRERRORSIZE];
+ isc_result_t result;
+ int optname;
+
+ result = isc_net_probeipv6();
+ if (result != ISC_R_SUCCESS) {
+ ipv6pktinfo_result = result;
+ return;
+ }
+
+ /* we only use this for UDP sockets */
+ s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (s == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6pktinfo_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+#ifdef IPV6_RECVPKTINFO
+ optname = IPV6_RECVPKTINFO;
+#else
+ optname = IPV6_PKTINFO;
+#endif
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, optname, &on, sizeof(on)) < 0) {
+ ipv6pktinfo_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ ipv6pktinfo_result = ISC_R_SUCCESS;
+
+close:
+ close(s);
+ return;
+}
+
+static void
+initialize_ipv6pktinfo(void) {
+ RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo,
+ try_ipv6pktinfo) == ISC_R_SUCCESS);
+}
+#endif /* ISC_PLATFORM_HAVEIN6PKTINFO */
+#endif /* WANT_IPV6 */
+#endif /* ISC_PLATFORM_HAVEIPV6 */
+
+isc_result_t
+isc_net_probe_ipv6only(void) {
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+ initialize_ipv6only();
+#else
+ ipv6only_result = ISC_R_NOTFOUND;
+#endif
+#endif
+ return (ipv6only_result);
+}
+
+isc_result_t
+isc_net_probe_ipv6pktinfo(void) {
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+#ifdef WANT_IPV6
+ initialize_ipv6pktinfo();
+#else
+ ipv6pktinfo_result = ISC_R_NOTFOUND;
+#endif
+#endif
+#endif
+ return (ipv6pktinfo_result);
+}
+
+#if defined(USE_SYSCTL_PORTRANGE)
+#if defined(HAVE_SYSCTLBYNAME)
+static isc_result_t
+getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) {
+ int port_low, port_high;
+ size_t portlen;
+ const char *sysctlname_lowport, *sysctlname_hiport;
+
+ if (af == AF_INET) {
+ sysctlname_lowport = SYSCTL_V4PORTRANGE_LOW;
+ sysctlname_hiport = SYSCTL_V4PORTRANGE_HIGH;
+ } else {
+ sysctlname_lowport = SYSCTL_V6PORTRANGE_LOW;
+ sysctlname_hiport = SYSCTL_V6PORTRANGE_HIGH;
+ }
+ portlen = sizeof(portlen);
+ if (sysctlbyname(sysctlname_lowport, &port_low, &portlen,
+ NULL, 0) < 0) {
+ return (ISC_R_FAILURE);
+ }
+ portlen = sizeof(portlen);
+ if (sysctlbyname(sysctlname_hiport, &port_high, &portlen,
+ NULL, 0) < 0) {
+ return (ISC_R_FAILURE);
+ }
+ if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0)
+ return (ISC_R_RANGE);
+
+ *low = (in_port_t)port_low;
+ *high = (in_port_t)port_high;
+
+ return (ISC_R_SUCCESS);
+}
+#else /* !HAVE_SYSCTLBYNAME */
+static isc_result_t
+getudpportrange_sysctl(int af, in_port_t *low, in_port_t *high) {
+ int mib_lo4[4] = SYSCTL_V4PORTRANGE_LOW;
+ int mib_hi4[4] = SYSCTL_V4PORTRANGE_HIGH;
+ int mib_lo6[4] = SYSCTL_V6PORTRANGE_LOW;
+ int mib_hi6[4] = SYSCTL_V6PORTRANGE_HIGH;
+ int *mib_lo, *mib_hi, miblen;
+ int port_low, port_high;
+ size_t portlen;
+
+ if (af == AF_INET) {
+ mib_lo = mib_lo4;
+ mib_hi = mib_hi4;
+ miblen = sizeof(mib_lo4) / sizeof(mib_lo4[0]);
+ } else {
+ mib_lo = mib_lo6;
+ mib_hi = mib_hi6;
+ miblen = sizeof(mib_lo6) / sizeof(mib_lo6[0]);
+ }
+
+ portlen = sizeof(portlen);
+ if (sysctl(mib_lo, miblen, &port_low, &portlen, NULL, 0) < 0) {
+ return (ISC_R_FAILURE);
+ }
+
+ portlen = sizeof(portlen);
+ if (sysctl(mib_hi, miblen, &port_high, &portlen, NULL, 0) < 0) {
+ return (ISC_R_FAILURE);
+ }
+
+ if ((port_low & ~0xffff) != 0 || (port_high & ~0xffff) != 0)
+ return (ISC_R_RANGE);
+
+ *low = (in_port_t) port_low;
+ *high = (in_port_t) port_high;
+
+ return (ISC_R_SUCCESS);
+}
+#endif /* HAVE_SYSCTLBYNAME */
+#endif /* USE_SYSCTL_PORTRANGE */
+
+isc_result_t
+isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) {
+ int result = ISC_R_FAILURE;
+
+ REQUIRE(low != NULL && high != NULL);
+
+#if defined(USE_SYSCTL_PORTRANGE)
+ result = getudpportrange_sysctl(af, low, high);
+#else
+ UNUSED(af);
+#endif
+
+ if (result != ISC_R_SUCCESS) {
+ *low = ISC_NET_PORTRANGELOW;
+ *high = ISC_NET_PORTRANGEHIGH;
+ }
+
+ return (ISC_R_SUCCESS); /* we currently never fail in this function */
+}
+
+void
+isc_net_disableipv4(void) {
+ initialize();
+ if (ipv4_result == ISC_R_SUCCESS)
+ ipv4_result = ISC_R_DISABLED;
+}
+
+void
+isc_net_disableipv6(void) {
+ initialize();
+ if (ipv6_result == ISC_R_SUCCESS)
+ ipv6_result = ISC_R_DISABLED;
+}
+
+void
+isc_net_enableipv4(void) {
+ initialize();
+ if (ipv4_result == ISC_R_DISABLED)
+ ipv4_result = ISC_R_SUCCESS;
+}
+
+void
+isc_net_enableipv6(void) {
+ initialize();
+ if (ipv6_result == ISC_R_DISABLED)
+ ipv6_result = ISC_R_SUCCESS;
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/stdio.c b/contrib/ntp/libntp/lib/isc/unix/stdio.c
new file mode 100644
index 000000000000..360c8c644afc
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/stdio.c
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2004, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <isc/stdio.h>
+#include <isc/stat.h>
+
+#include "errno2result.h"
+
+isc_result_t
+isc_stdio_open(const char *filename, const char *mode, FILE **fp) {
+ FILE *f;
+
+ f = fopen(filename, mode);
+ if (f == NULL)
+ return (isc__errno2result(errno));
+ *fp = f;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_stdio_close(FILE *f) {
+ int r;
+
+ r = fclose(f);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+isc_result_t
+isc_stdio_seek(FILE *f, long offset, int whence) {
+ int r;
+
+ r = fseek(f, offset, whence);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+isc_result_t
+isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) {
+ isc_result_t result = ISC_R_SUCCESS;
+ size_t r;
+
+ clearerr(f);
+ r = fread(ptr, size, nmemb, f);
+ if (r != nmemb) {
+ if (feof(f))
+ result = ISC_R_EOF;
+ else
+ result = isc__errno2result(errno);
+ }
+ if (nret != NULL)
+ *nret = r;
+ return (result);
+}
+
+isc_result_t
+isc_stdio_write(const void *ptr, size_t size, size_t nmemb, FILE *f,
+ size_t *nret)
+{
+ isc_result_t result = ISC_R_SUCCESS;
+ size_t r;
+
+ clearerr(f);
+ r = fwrite(ptr, size, nmemb, f);
+ if (r != nmemb)
+ result = isc__errno2result(errno);
+ if (nret != NULL)
+ *nret = r;
+ return (result);
+}
+
+isc_result_t
+isc_stdio_flush(FILE *f) {
+ int r;
+
+ r = fflush(f);
+ if (r == 0)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
+/*
+ * OpenBSD has deprecated ENOTSUP in favor of EOPNOTSUPP.
+ */
+#if defined(EOPNOTSUPP) && !defined(ENOTSUP)
+#define ENOTSUP EOPNOTSUPP
+#endif
+
+isc_result_t
+isc_stdio_sync(FILE *f) {
+ int r;
+
+ r = fsync(fileno(f));
+ /*
+ * fsync is not supported on sockets and pipes which
+ * result in EINVAL / ENOTSUP.
+ */
+ if (r == 0 || errno == EINVAL || errno == ENOTSUP)
+ return (ISC_R_SUCCESS);
+ else
+ return (isc__errno2result(errno));
+}
+
diff --git a/contrib/ntp/libntp/lib/isc/unix/stdtime.c b/contrib/ntp/libntp/lib/isc/unix/stdtime.c
new file mode 100644
index 000000000000..c5d0c47df1fc
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/stdtime.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: stdtime.c,v 1.19 2007/06/19 23:47:18 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stddef.h> /* NULL */
+#include <stdlib.h> /* NULL */
+#include <syslog.h>
+
+#include <sys/time.h>
+
+#include <isc/stdtime.h>
+#include <isc/util.h>
+
+#ifndef ISC_FIX_TV_USEC
+#define ISC_FIX_TV_USEC 1
+#endif
+
+#define US_PER_S 1000000
+
+#if ISC_FIX_TV_USEC
+static inline void
+fix_tv_usec(struct timeval *tv) {
+ isc_boolean_t fixed = ISC_FALSE;
+
+ if (tv->tv_usec < 0) {
+ fixed = ISC_TRUE;
+ do {
+ tv->tv_sec -= 1;
+ tv->tv_usec += US_PER_S;
+ } while (tv->tv_usec < 0);
+ } else if (tv->tv_usec >= US_PER_S) {
+ fixed = ISC_TRUE;
+ do {
+ tv->tv_sec += 1;
+ tv->tv_usec -= US_PER_S;
+ } while (tv->tv_usec >=US_PER_S);
+ }
+ /*
+ * Call syslog directly as we are called from the logging functions.
+ */
+ if (fixed)
+ (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected");
+}
+#endif
+
+void
+isc_stdtime_get(isc_stdtime_t *t) {
+ struct timeval tv;
+
+ /*
+ * Set 't' to the number of seconds since 00:00:00 UTC, January 1,
+ * 1970.
+ */
+
+ REQUIRE(t != NULL);
+
+ RUNTIME_CHECK(gettimeofday(&tv, NULL) != -1);
+
+#if ISC_FIX_TV_USEC
+ fix_tv_usec(&tv);
+ INSIST(tv.tv_usec >= 0);
+#else
+ INSIST(tv.tv_usec >= 0 && tv.tv_usec < US_PER_S);
+#endif
+
+ *t = (unsigned int)tv.tv_sec;
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/strerror.c b/contrib/ntp/libntp/lib/isc/unix/strerror.c
new file mode 100644
index 000000000000..22780095b546
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/strerror.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: strerror.c,v 1.10 2009/02/16 23:48:04 tbox Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/print.h>
+#include <isc/strerror.h>
+#include <isc/util.h>
+
+#include "l_stdlib.h" /* NTP local change */
+
+#ifdef HAVE_STRERROR
+/*%
+ * We need to do this this way for profiled locks.
+ */
+static isc_mutex_t isc_strerror_lock;
+static void init_lock(void) {
+ RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS);
+}
+#else
+extern const char * const sys_errlist[];
+extern const int sys_nerr;
+#endif
+
+void
+isc__strerror(int num, char *buf, size_t size) {
+#ifdef HAVE_STRERROR
+ char *msg;
+ unsigned int unum = (unsigned int)num;
+ static isc_once_t once = ISC_ONCE_INIT;
+
+ REQUIRE(buf != NULL);
+
+ RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
+
+ LOCK(&isc_strerror_lock);
+ msg = strerror(num);
+ if (msg != NULL)
+ snprintf(buf, size, "%s", msg);
+ else
+ snprintf(buf, size, "Unknown error: %u", unum);
+ UNLOCK(&isc_strerror_lock);
+#else
+ unsigned int unum = (unsigned int)num;
+
+ REQUIRE(buf != NULL);
+
+ if (num >= 0 && num < sys_nerr)
+ snprintf(buf, size, "%s", sys_errlist[num]);
+ else
+ snprintf(buf, size, "Unknown error: %u", unum);
+#endif
+}
diff --git a/contrib/ntp/libntp/lib/isc/unix/time.c b/contrib/ntp/libntp/lib/isc/unix/time.c
new file mode 100644
index 000000000000..ac23ae092804
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/unix/time.c
@@ -0,0 +1,420 @@
+/*
+ * Copyright (C) 2004-2008, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <syslog.h>
+#include <time.h>
+
+#include <sys/time.h> /* Required for struct timeval on some platforms. */
+
+#include <isc/log.h>
+#include <isc/print.h>
+#include <isc/strerror.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+#define NS_PER_S 1000000000 /*%< Nanoseconds per second. */
+#define NS_PER_US 1000 /*%< Nanoseconds per microsecond. */
+#define US_PER_S 1000000 /*%< Microseconds per second. */
+
+/*
+ * All of the INSIST()s checks of nanoseconds < NS_PER_S are for
+ * consistency checking of the type. In lieu of magic numbers, it
+ * is the best we've got. The check is only performed on functions which
+ * need an initialized type.
+ */
+
+#ifndef ISC_FIX_TV_USEC
+#define ISC_FIX_TV_USEC 1
+#endif
+
+/*%
+ *** Intervals
+ ***/
+
+static isc_interval_t zero_interval = { 0, 0 };
+isc_interval_t *isc_interval_zero = &zero_interval;
+
+#if ISC_FIX_TV_USEC
+static inline void
+fix_tv_usec(struct timeval *tv) {
+ isc_boolean_t fixed = ISC_FALSE;
+
+ if (tv->tv_usec < 0) {
+ fixed = ISC_TRUE;
+ do {
+ tv->tv_sec -= 1;
+ tv->tv_usec += US_PER_S;
+ } while (tv->tv_usec < 0);
+ } else if (tv->tv_usec >= US_PER_S) {
+ fixed = ISC_TRUE;
+ do {
+ tv->tv_sec += 1;
+ tv->tv_usec -= US_PER_S;
+ } while (tv->tv_usec >=US_PER_S);
+ }
+ /*
+ * Call syslog directly as was are called from the logging functions.
+ */
+ if (fixed)
+ (void)syslog(LOG_ERR, "gettimeofday returned bad tv_usec: corrected");
+}
+#endif
+
+void
+isc_interval_set(isc_interval_t *i,
+ unsigned int seconds, unsigned int nanoseconds)
+{
+ REQUIRE(i != NULL);
+ REQUIRE(nanoseconds < NS_PER_S);
+
+ i->seconds = seconds;
+ i->nanoseconds = nanoseconds;
+}
+
+isc_boolean_t
+isc_interval_iszero(const isc_interval_t *i) {
+ REQUIRE(i != NULL);
+ INSIST(i->nanoseconds < NS_PER_S);
+
+ if (i->seconds == 0 && i->nanoseconds == 0)
+ return (ISC_TRUE);
+
+ return (ISC_FALSE);
+}
+
+
+/***
+ *** Absolute Times
+ ***/
+
+static isc_time_t epoch = { 0, 0 };
+isc_time_t *isc_time_epoch = &epoch;
+
+void
+isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
+ REQUIRE(t != NULL);
+ REQUIRE(nanoseconds < NS_PER_S);
+
+ t->seconds = seconds;
+ t->nanoseconds = nanoseconds;
+}
+
+void
+isc_time_settoepoch(isc_time_t *t) {
+ REQUIRE(t != NULL);
+
+ t->seconds = 0;
+ t->nanoseconds = 0;
+}
+
+isc_boolean_t
+isc_time_isepoch(const isc_time_t *t) {
+ REQUIRE(t != NULL);
+ INSIST(t->nanoseconds < NS_PER_S);
+
+ if (t->seconds == 0 && t->nanoseconds == 0)
+ return (ISC_TRUE);
+
+ return (ISC_FALSE);
+}
+
+
+isc_result_t
+isc_time_now(isc_time_t *t) {
+ struct timeval tv;
+ char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(t != NULL);
+
+ if (gettimeofday(&tv, NULL) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+
+ /*
+ * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not,
+ * then this test will generate warnings for platforms on which it is
+ * unsigned. In any event, the chances of any of these problems
+ * happening are pretty much zero, but since the libisc library ensures
+ * certain things to be true ...
+ */
+#if ISC_FIX_TV_USEC
+ fix_tv_usec(&tv);
+ if (tv.tv_sec < 0)
+ return (ISC_R_UNEXPECTED);
+#else
+ if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S)
+ return (ISC_R_UNEXPECTED);
+#endif
+
+ /*
+ * Ensure the tv_sec value fits in t->seconds.
+ */
+ if (sizeof(tv.tv_sec) > sizeof(t->seconds) &&
+ ((tv.tv_sec | (unsigned int)-1) ^ (unsigned int)-1) != 0U)
+ return (ISC_R_RANGE);
+
+ t->seconds = tv.tv_sec;
+ t->nanoseconds = tv.tv_usec * NS_PER_US;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
+ struct timeval tv;
+ char strbuf[ISC_STRERRORSIZE];
+
+ REQUIRE(t != NULL);
+ REQUIRE(i != NULL);
+ INSIST(i->nanoseconds < NS_PER_S);
+
+ if (gettimeofday(&tv, NULL) == -1) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__, "%s", strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+
+ /*
+ * Does POSIX guarantee the signedness of tv_sec and tv_usec? If not,
+ * then this test will generate warnings for platforms on which it is
+ * unsigned. In any event, the chances of any of these problems
+ * happening are pretty much zero, but since the libisc library ensures
+ * certain things to be true ...
+ */
+#if ISC_FIX_TV_USEC
+ fix_tv_usec(&tv);
+ if (tv.tv_sec < 0)
+ return (ISC_R_UNEXPECTED);
+#else
+ if (tv.tv_sec < 0 || tv.tv_usec < 0 || tv.tv_usec >= US_PER_S)
+ return (ISC_R_UNEXPECTED);
+#endif
+
+ /*
+ * Ensure the resulting seconds value fits in the size of an
+ * unsigned int. (It is written this way as a slight optimization;
+ * note that even if both values == INT_MAX, then when added
+ * and getting another 1 added below the result is UINT_MAX.)
+ */
+ if ((tv.tv_sec > INT_MAX || i->seconds > INT_MAX) &&
+ ((long long)tv.tv_sec + i->seconds > UINT_MAX))
+ return (ISC_R_RANGE);
+
+ t->seconds = tv.tv_sec + i->seconds;
+ t->nanoseconds = tv.tv_usec * NS_PER_US + i->nanoseconds;
+ if (t->nanoseconds >= NS_PER_S) {
+ t->seconds++;
+ t->nanoseconds -= NS_PER_S;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+int
+isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) {
+ REQUIRE(t1 != NULL && t2 != NULL);
+ INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S);
+
+ if (t1->seconds < t2->seconds)
+ return (-1);
+ if (t1->seconds > t2->seconds)
+ return (1);
+ if (t1->nanoseconds < t2->nanoseconds)
+ return (-1);
+ if (t1->nanoseconds > t2->nanoseconds)
+ return (1);
+ return (0);
+}
+
+isc_result_t
+isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result)
+{
+ REQUIRE(t != NULL && i != NULL && result != NULL);
+ INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S);
+
+ /*
+ * Ensure the resulting seconds value fits in the size of an
+ * unsigned int. (It is written this way as a slight optimization;
+ * note that even if both values == INT_MAX, then when added
+ * and getting another 1 added below the result is UINT_MAX.)
+ */
+ if ((t->seconds > INT_MAX || i->seconds > INT_MAX) &&
+ ((long long)t->seconds + i->seconds > UINT_MAX))
+ return (ISC_R_RANGE);
+
+ result->seconds = t->seconds + i->seconds;
+ result->nanoseconds = t->nanoseconds + i->nanoseconds;
+ if (result->nanoseconds >= NS_PER_S) {
+ result->seconds++;
+ result->nanoseconds -= NS_PER_S;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
+ isc_time_t *result)
+{
+ REQUIRE(t != NULL && i != NULL && result != NULL);
+ INSIST(t->nanoseconds < NS_PER_S && i->nanoseconds < NS_PER_S);
+
+ if ((unsigned int)t->seconds < i->seconds ||
+ ((unsigned int)t->seconds == i->seconds &&
+ t->nanoseconds < i->nanoseconds))
+ return (ISC_R_RANGE);
+
+ result->seconds = t->seconds - i->seconds;
+ if (t->nanoseconds >= i->nanoseconds)
+ result->nanoseconds = t->nanoseconds - i->nanoseconds;
+ else {
+ result->nanoseconds = NS_PER_S - i->nanoseconds +
+ t->nanoseconds;
+ result->seconds--;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_uint64_t
+isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
+ isc_uint64_t i1, i2, i3;
+
+ REQUIRE(t1 != NULL && t2 != NULL);
+ INSIST(t1->nanoseconds < NS_PER_S && t2->nanoseconds < NS_PER_S);
+
+ i1 = (isc_uint64_t)t1->seconds * NS_PER_S + t1->nanoseconds;
+ i2 = (isc_uint64_t)t2->seconds * NS_PER_S + t2->nanoseconds;
+
+ if (i1 <= i2)
+ return (0);
+
+ i3 = i1 - i2;
+
+ /*
+ * Convert to microseconds.
+ */
+ i3 /= NS_PER_US;
+
+ return (i3);
+}
+
+isc_uint32_t
+isc_time_seconds(const isc_time_t *t) {
+ REQUIRE(t != NULL);
+ INSIST(t->nanoseconds < NS_PER_S);
+
+ return ((isc_uint32_t)t->seconds);
+}
+
+isc_result_t
+isc_time_secondsastimet(const isc_time_t *t, time_t *secondsp) {
+ time_t seconds;
+
+ REQUIRE(t != NULL);
+ INSIST(t->nanoseconds < NS_PER_S);
+
+ /*
+ * Ensure that the number of seconds represented by t->seconds
+ * can be represented by a time_t. Since t->seconds is an unsigned
+ * int and since time_t is mostly opaque, this is trickier than
+ * it seems. (This standardized opaqueness of time_t is *very*
+ * frustrating; time_t is not even limited to being an integral
+ * type.)
+ *
+ * The mission, then, is to avoid generating any kind of warning
+ * about "signed versus unsigned" while trying to determine if the
+ * the unsigned int t->seconds is out range for tv_sec, which is
+ * pretty much only true if time_t is a signed integer of the same
+ * size as the return value of isc_time_seconds.
+ *
+ * If the paradox in the if clause below is true, t->seconds is out
+ * of range for time_t.
+ */
+ seconds = (time_t)t->seconds;
+
+ INSIST(sizeof(unsigned int) == sizeof(isc_uint32_t));
+ INSIST(sizeof(time_t) >= sizeof(isc_uint32_t));
+
+ if (t->seconds > (~0U>>1) && seconds <= (time_t)(~0U>>1))
+ return (ISC_R_RANGE);
+
+ *secondsp = seconds;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_uint32_t
+isc_time_nanoseconds(const isc_time_t *t) {
+ REQUIRE(t != NULL);
+
+ ENSURE(t->nanoseconds < NS_PER_S);
+
+ return ((isc_uint32_t)t->nanoseconds);
+}
+
+void
+isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
+ time_t now;
+ unsigned int flen;
+
+ REQUIRE(len > 0);
+
+ now = (time_t) t->seconds;
+ flen = strftime(buf, len, "%d-%b-%Y %X", localtime(&now));
+ INSIST(flen < len);
+ if (flen != 0)
+ snprintf(buf + flen, len - flen,
+ ".%03u", t->nanoseconds / 1000000);
+ else
+ snprintf(buf, len, "99-Bad-9999 99:99:99.999");
+}
+
+void
+isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
+ time_t now;
+ unsigned int flen;
+
+ REQUIRE(len > 0);
+
+ now = (time_t)t->seconds;
+ flen = strftime(buf, len, "%a, %d %b %Y %H:%M:%S GMT", gmtime(&now));
+ INSIST(flen < len);
+}
+
+void
+isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) {
+ time_t now;
+ unsigned int flen;
+
+ REQUIRE(len > 0);
+
+ now = (time_t)t->seconds;
+ flen = strftime(buf, len, "%Y-%m-%dT%H:%M:%SZ", gmtime(&now));
+ INSIST(flen < len);
+}
diff --git a/contrib/ntp/libntp/lib/isc/win32/condition.c b/contrib/ntp/libntp/lib/isc/win32/condition.c
new file mode 100644
index 000000000000..27d4e7607037
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/condition.c
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: condition.c,v 1.23 2007/06/18 23:47:49 tbox Exp $ */
+
+#include <config.h>
+
+#include <isc/condition.h>
+#include <isc/assertions.h>
+#include <isc/util.h>
+#include <isc/thread.h>
+#include <isc/time.h>
+
+#define LSIGNAL 0
+#define LBROADCAST 1
+
+isc_result_t
+isc_condition_init(isc_condition_t *cond) {
+ HANDLE h;
+
+ REQUIRE(cond != NULL);
+
+ cond->waiters = 0;
+ /*
+ * This handle is shared across all threads
+ */
+ h = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (h == NULL) {
+ /* XXX */
+ return (ISC_R_UNEXPECTED);
+ }
+ cond->events[LSIGNAL] = h;
+
+ /*
+ * The threadlist will hold the actual events needed
+ * for the wait condition
+ */
+ ISC_LIST_INIT(cond->threadlist);
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Add the thread to the threadlist along with the required events
+ */
+static isc_result_t
+register_thread(unsigned long thrd, isc_condition_t *gblcond,
+ isc_condition_thread_t **localcond)
+{
+ HANDLE hc;
+ isc_condition_thread_t *newthread;
+
+ REQUIRE(localcond != NULL && *localcond == NULL);
+
+ newthread = malloc(sizeof(isc_condition_thread_t));
+ if (newthread == NULL)
+ return (ISC_R_NOMEMORY);
+
+ /*
+ * Create the thread-specific handle
+ */
+ hc = CreateEvent(NULL, FALSE, FALSE, NULL);
+ if (hc == NULL) {
+ free(newthread);
+ return (ISC_R_UNEXPECTED);
+ }
+
+ /*
+ * Add the thread ID and handles to list of threads for broadcast
+ */
+ newthread->handle[LSIGNAL] = gblcond->events[LSIGNAL];
+ newthread->handle[LBROADCAST] = hc;
+ newthread->th = thrd;
+
+ /*
+ * The thread is holding the manager lock so this is safe
+ */
+ ISC_LIST_APPEND(gblcond->threadlist, newthread, link);
+ *localcond = newthread;
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+find_thread_condition(unsigned long thrd, isc_condition_t *cond,
+ isc_condition_thread_t **threadcondp)
+{
+ isc_condition_thread_t *threadcond;
+
+ REQUIRE(threadcondp != NULL && *threadcondp == NULL);
+
+ /*
+ * Look for the thread ID.
+ */
+ for (threadcond = ISC_LIST_HEAD(cond->threadlist);
+ threadcond != NULL;
+ threadcond = ISC_LIST_NEXT(threadcond, link)) {
+
+ if (threadcond->th == thrd) {
+ *threadcondp = threadcond;
+ return (ISC_R_SUCCESS);
+ }
+ }
+
+ /*
+ * Not found, so add it.
+ */
+ return (register_thread(thrd, cond, threadcondp));
+}
+
+isc_result_t
+isc_condition_signal(isc_condition_t *cond) {
+
+ /*
+ * Unlike pthreads, the caller MUST hold the lock associated with
+ * the condition variable when calling us.
+ */
+ REQUIRE(cond != NULL);
+
+ if (!SetEvent(cond->events[LSIGNAL])) {
+ /* XXX */
+ return (ISC_R_UNEXPECTED);
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_condition_broadcast(isc_condition_t *cond) {
+
+ isc_condition_thread_t *threadcond;
+ isc_boolean_t failed = ISC_FALSE;
+
+ /*
+ * Unlike pthreads, the caller MUST hold the lock associated with
+ * the condition variable when calling us.
+ */
+ REQUIRE(cond != NULL);
+
+ /*
+ * Notify every thread registered for this
+ */
+ for (threadcond = ISC_LIST_HEAD(cond->threadlist);
+ threadcond != NULL;
+ threadcond = ISC_LIST_NEXT(threadcond, link)) {
+
+ if (!SetEvent(threadcond->handle[LBROADCAST]))
+ failed = ISC_TRUE;
+ }
+
+ if (failed)
+ return (ISC_R_UNEXPECTED);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_condition_destroy(isc_condition_t *cond) {
+
+ isc_condition_thread_t *next, *threadcond;
+
+ REQUIRE(cond != NULL);
+ REQUIRE(cond->waiters == 0);
+
+ (void)CloseHandle(cond->events[LSIGNAL]);
+
+ /*
+ * Delete the threadlist
+ */
+ threadcond = ISC_LIST_HEAD(cond->threadlist);
+
+ while (threadcond != NULL) {
+ next = ISC_LIST_NEXT(threadcond, link);
+ DEQUEUE(cond->threadlist, threadcond, link);
+ (void) CloseHandle(threadcond->handle[LBROADCAST]);
+ free(threadcond);
+ threadcond = next;
+ }
+
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * This is always called when the mutex (lock) is held, but because
+ * we are waiting we need to release it and reacquire it as soon as the wait
+ * is over. This allows other threads to make use of the object guarded
+ * by the mutex but it should never try to delete it as long as the
+ * number of waiters > 0. Always reacquire the mutex regardless of the
+ * result of the wait. Note that EnterCriticalSection will wait to acquire
+ * the mutex.
+ */
+static isc_result_t
+wait(isc_condition_t *cond, isc_mutex_t *mutex, DWORD milliseconds) {
+ DWORD result;
+ isc_result_t tresult;
+ isc_condition_thread_t *threadcond = NULL;
+
+ /*
+ * Get the thread events needed for the wait
+ */
+ tresult = find_thread_condition(isc_thread_self(), cond, &threadcond);
+ if (tresult != ISC_R_SUCCESS)
+ return (tresult);
+
+ cond->waiters++;
+ LeaveCriticalSection(mutex);
+ result = WaitForMultipleObjects(2, threadcond->handle, FALSE,
+ milliseconds);
+ EnterCriticalSection(mutex);
+ cond->waiters--;
+ if (result == WAIT_FAILED) {
+ /* XXX */
+ return (ISC_R_UNEXPECTED);
+ }
+ if (result == WAIT_TIMEOUT)
+ return (ISC_R_TIMEDOUT);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_condition_wait(isc_condition_t *cond, isc_mutex_t *mutex) {
+ return (wait(cond, mutex, INFINITE));
+}
+
+isc_result_t
+isc_condition_waituntil(isc_condition_t *cond, isc_mutex_t *mutex,
+ isc_time_t *t) {
+ DWORD milliseconds;
+ isc_uint64_t microseconds;
+ isc_time_t now;
+
+ if (isc_time_now(&now) != ISC_R_SUCCESS) {
+ /* XXX */
+ return (ISC_R_UNEXPECTED);
+ }
+
+ microseconds = isc_time_microdiff(t, &now);
+ if (microseconds > 0xFFFFFFFFi64 * 1000)
+ milliseconds = 0xFFFFFFFF;
+ else
+ milliseconds = (DWORD)(microseconds / 1000);
+
+ return (wait(cond, mutex, milliseconds));
+}
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/condition.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/condition.h
new file mode 100644
index 000000000000..34015bc26562
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/condition.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: condition.h,v 1.17 2007/06/18 23:47:49 tbox Exp $ */
+
+#ifndef ISC_CONDITION_H
+#define ISC_CONDITION_H 1
+
+#include <windows.h>
+
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/thread.h>
+#include <isc/types.h>
+
+typedef struct isc_condition_thread isc_condition_thread_t;
+
+struct isc_condition_thread {
+ unsigned long th;
+ HANDLE handle[2];
+ ISC_LINK(isc_condition_thread_t) link;
+
+};
+
+typedef struct isc_condition {
+ HANDLE events[2];
+ unsigned int waiters;
+ ISC_LIST(isc_condition_thread_t) threadlist;
+} isc_condition_t;
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_condition_init(isc_condition_t *);
+
+isc_result_t
+isc_condition_wait(isc_condition_t *, isc_mutex_t *);
+
+isc_result_t
+isc_condition_signal(isc_condition_t *);
+
+isc_result_t
+isc_condition_broadcast(isc_condition_t *);
+
+isc_result_t
+isc_condition_destroy(isc_condition_t *);
+
+isc_result_t
+isc_condition_waituntil(isc_condition_t *, isc_mutex_t *, isc_time_t *);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_CONDITION_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/dir.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/dir.h
new file mode 100644
index 000000000000..653427a9720e
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/dir.h
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: dir.h,v 1.15 2007/06/19 23:47:20 tbox Exp $ */
+
+/* Principal Authors: DCL */
+
+#ifndef ISC_DIR_H
+#define ISC_DIR_H 1
+
+#include <windows.h>
+#include <stdlib.h>
+
+#include <isc/lang.h>
+#include <isc/boolean.h>
+#include <isc/result.h>
+
+#define ISC_DIR_NAMEMAX _MAX_FNAME
+#define ISC_DIR_PATHMAX _MAX_PATH
+
+typedef struct {
+ char name[ISC_DIR_NAMEMAX];
+ unsigned int length;
+ WIN32_FIND_DATA find_data;
+} isc_direntry_t;
+
+typedef struct {
+ unsigned int magic;
+ char dirname[ISC_DIR_PATHMAX];
+ isc_direntry_t entry;
+ isc_boolean_t entry_filled;
+ HANDLE search_handle;
+} isc_dir_t;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_dir_init(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_open(isc_dir_t *dir, const char *dirname);
+
+isc_result_t
+isc_dir_read(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_reset(isc_dir_t *dir);
+
+void
+isc_dir_close(isc_dir_t *dir);
+
+isc_result_t
+isc_dir_chdir(const char *dirname);
+
+isc_result_t
+isc_dir_chroot(const char *dirname);
+
+isc_result_t
+isc_dir_createunique(char *templet);
+/*
+ * Use a templet (such as from isc_file_mktemplate()) to create a uniquely
+ * named, empty directory. The templet string is modified in place.
+ * If result == ISC_R_SUCCESS, it is the name of the directory that was
+ * created.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_DIR_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/int.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/int.h
new file mode 100644
index 000000000000..edcf59dd3ad7
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/int.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: int.h,v 1.13 2007/06/19 23:47:20 tbox Exp $ */
+
+#ifndef ISC_INT_H
+#define ISC_INT_H 1
+
+#ifndef _INTEGRAL_MAX_BITS
+# define _INTEGRAL_MAX_BITS 64
+#endif
+#include <limits.h>
+
+typedef __int8 isc_int8_t;
+typedef unsigned __int8 isc_uint8_t;
+typedef __int16 isc_int16_t;
+typedef unsigned __int16 isc_uint16_t;
+typedef __int32 isc_int32_t;
+typedef unsigned __int32 isc_uint32_t;
+typedef __int64 isc_int64_t;
+typedef unsigned __int64 isc_uint64_t;
+
+#define ISC_INT8_MIN -128
+#define ISC_INT8_MAX 127
+#define ISC_UINT8_MAX 255
+
+#define ISC_INT16_MIN -32768
+#define ISC_INT16_MAX 32767
+#define ISC_UINT16_MAX 65535
+
+/*
+ * Note that "int" is 32 bits on all currently supported Unix-like operating
+ * systems, but "long" can be either 32 bits or 64 bits, thus the 32 bit
+ * constants are not qualified with "L".
+ */
+#define ISC_INT32_MIN _I32_MIN
+#define ISC_INT32_MAX _I32_MAX
+#define ISC_UINT32_MAX _UI32_MAX
+
+#define ISC_INT64_MIN _I64_MIN
+#define ISC_INT64_MAX _I64_MAX
+#define ISC_UINT64_MAX _UI64_MAX
+
+#endif /* ISC_INT_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/ipv6.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/ipv6.h
new file mode 100644
index 000000000000..27384a3557f7
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/ipv6.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_IPV6_H
+#define ISC_IPV6_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * IPv6 definitions for systems which do not support IPv6.
+ *
+ * MP:
+ * No impact.
+ *
+ * Reliability:
+ * No anticipated impact.
+ *
+ * Resources:
+ * N/A.
+ *
+ * Security:
+ * No anticipated impact.
+ *
+ * Standards:
+ * RFC2553.
+ */
+
+#if _MSC_VER < 1300
+#define in6_addr in_addr6
+#endif
+
+#ifndef IN6ADDR_ANY_INIT
+#define IN6ADDR_ANY_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}
+#endif
+#ifndef IN6ADDR_LOOPBACK_INIT
+#define IN6ADDR_LOOPBACK_INIT {{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}
+#endif
+
+LIBISC_EXTERNAL_DATA extern const struct in6_addr isc_net_in6addrany;
+LIBISC_EXTERNAL_DATA extern const struct in6_addr isc_net_in6addrloop;
+
+/*
+ * Unspecified
+ */
+#ifndef IN6_IS_ADDR_UNSPECIFIED
+#define IN6_IS_ADDR_UNSPECIFIED(a) (\
+*((u_long *)((a)->s6_addr) ) == 0 && \
+*((u_long *)((a)->s6_addr) + 1) == 0 && \
+*((u_long *)((a)->s6_addr) + 2) == 0 && \
+*((u_long *)((a)->s6_addr) + 3) == 0 \
+)
+#endif
+
+/*
+ * Loopback
+ */
+#ifndef IN6_IS_ADDR_LOOPBACK
+#define IN6_IS_ADDR_LOOPBACK(a) (\
+*((u_long *)((a)->s6_addr) ) == 0 && \
+*((u_long *)((a)->s6_addr) + 1) == 0 && \
+*((u_long *)((a)->s6_addr) + 2) == 0 && \
+*((u_long *)((a)->s6_addr) + 3) == htonl(1) \
+)
+#endif
+
+/*
+ * IPv4 compatible
+ */
+#define IN6_IS_ADDR_V4COMPAT(a) (\
+*((u_long *)((a)->s6_addr) ) == 0 && \
+*((u_long *)((a)->s6_addr) + 1) == 0 && \
+*((u_long *)((a)->s6_addr) + 2) == 0 && \
+*((u_long *)((a)->s6_addr) + 3) != 0 && \
+*((u_long *)((a)->s6_addr) + 3) != htonl(1) \
+)
+
+/*
+ * Mapped
+ */
+#define IN6_IS_ADDR_V4MAPPED(a) (\
+*((u_long *)((a)->s6_addr) ) == 0 && \
+*((u_long *)((a)->s6_addr) + 1) == 0 && \
+*((u_long *)((a)->s6_addr) + 2) == htonl(0x0000ffff))
+
+/*
+ * Multicast
+ */
+#define IN6_IS_ADDR_MULTICAST(a) \
+ ((a)->s6_addr[0] == 0xffU)
+
+/*
+ * Unicast link / site local.
+ */
+#ifndef IN6_IS_ADDR_LINKLOCAL
+#define IN6_IS_ADDR_LINKLOCAL(a) (\
+ ((a)->s6_addr[0] == 0xfe) && \
+ (((a)->s6_addr[1] & 0xc0) == 0x80))
+#endif
+
+#ifndef IN6_IS_ADDR_SITELOCAL
+#define IN6_IS_ADDR_SITELOCAL(a) (\
+ ((a)->s6_addr[0] == 0xfe) && \
+ (((a)->s6_addr[1] & 0xc0) == 0xc0))
+#endif
+
+#endif /* ISC_IPV6_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/mutex.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/mutex.h
new file mode 100644
index 000000000000..5cf1bae1ba60
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/mutex.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: mutex.h,v 1.22 2009/01/18 23:48:14 tbox Exp $ */
+
+#ifndef ISC_MUTEX_H
+#define ISC_MUTEX_H 1
+
+#include <isc/net.h>
+#include <windows.h>
+
+#include <isc/result.h>
+
+typedef CRITICAL_SECTION isc_mutex_t;
+
+/*
+ * This definition is here since some versions of WINBASE.H
+ * omits it for some reason.
+ */
+#if (_WIN32_WINNT < 0x0400)
+WINBASEAPI BOOL WINAPI
+TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection);
+#endif /* _WIN32_WINNT < 0x0400 */
+
+#define isc_mutex_init(mp) \
+ (InitializeCriticalSection((mp)), ISC_R_SUCCESS)
+#define isc_mutex_lock(mp) \
+ (EnterCriticalSection((mp)), ISC_R_SUCCESS)
+#define isc_mutex_unlock(mp) \
+ (LeaveCriticalSection((mp)), ISC_R_SUCCESS)
+#define isc_mutex_trylock(mp) \
+ (TryEnterCriticalSection((mp)) ? ISC_R_SUCCESS : ISC_R_LOCKBUSY)
+#define isc_mutex_destroy(mp) \
+ (DeleteCriticalSection((mp)), ISC_R_SUCCESS)
+
+/*
+ * This is a placeholder for now since we are not keeping any mutex stats
+ */
+#define isc_mutex_stats(fp) do {} while (0)
+
+#endif /* ISC_MUTEX_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/net.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/net.h
new file mode 100644
index 000000000000..10be85b44408
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/net.h
@@ -0,0 +1,374 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2008, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_NET_H
+#define ISC_NET_H 1
+
+#include <errno.h>
+
+/*
+ * Also define LWRES_IPV6_H to keep it from being included if liblwres is
+ * being used, or redefinition errors will occur.
+ */
+#define LWRES_IPV6_H 1
+
+
+
+/*****
+ ***** Module Info
+ *****/
+
+/*
+ * Basic Networking Types
+ *
+ * This module is responsible for defining the following basic networking
+ * types:
+ *
+ * struct in_addr
+ * struct in6_addr
+ * struct in6_pktinfo
+ * struct sockaddr
+ * struct sockaddr_in
+ * struct sockaddr_in6
+ * in_port_t
+ *
+ * It ensures that the AF_ and PF_ macros are defined.
+ *
+ * It declares ntoh[sl]() and hton[sl]().
+ *
+ * It declares inet_aton(), inet_ntop(), and inet_pton().
+ *
+ * It ensures that INADDR_ANY, IN6ADDR_ANY_INIT, in6addr_any, and
+ * in6addr_loopback are available.
+ *
+ * It ensures that IN_MULTICAST() is available to check for multicast
+ * addresses.
+ *
+ * MP:
+ * No impact.
+ *
+ * Reliability:
+ * No anticipated impact.
+ *
+ * Resources:
+ * N/A.
+ *
+ * Security:
+ * No anticipated impact.
+ *
+ * Standards:
+ * BSD Socket API
+ * RFC2553
+ */
+
+/***
+ *** Imports.
+ ***/
+#include <isc/platform.h>
+
+/*
+ * Because of some sort of problem in the MS header files, this cannot
+ * be simple "#include <winsock2.h>", because winsock2.h tries to include
+ * windows.h, which then generates an error out of mswsock.h. _You_
+ * figure it out.
+ */
+#ifndef _WINSOCKAPI_
+#define _WINSOCKAPI_ /* Prevent inclusion of winsock.h in windows.h */
+#endif
+
+#include <winsock2.h>
+
+#include <sys/types.h>
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#include <ws2tcpip.h>
+#include <isc/ipv6.h>
+
+/*
+ * This is here because named client, interfacemgr.c, etc. use the name as
+ * a variable
+ */
+#undef interface
+
+#ifndef INADDR_LOOPBACK
+#define INADDR_LOOPBACK 0x7f000001UL
+#endif
+
+#ifndef ISC_PLATFORM_HAVEIN6PKTINFO
+struct in6_pktinfo {
+ struct in6_addr ipi6_addr; /* src/dst IPv6 address */
+ unsigned int ipi6_ifindex; /* send/recv interface index */
+};
+#endif
+
+#if _MSC_VER < 1300
+#define in6addr_any isc_net_in6addrany
+#define in6addr_loopback isc_net_in6addrloop
+#endif
+
+/*
+ * Ensure type in_port_t is defined.
+ */
+#ifdef ISC_PLATFORM_NEEDPORTT
+typedef isc_uint16_t in_port_t;
+#endif
+
+/*
+ * If this system does not have MSG_TRUNC (as returned from recvmsg())
+ * ISC_PLATFORM_RECVOVERFLOW will be defined. This will enable the MSG_TRUNC
+ * faking code in socket.c.
+ */
+#ifndef MSG_TRUNC
+#define ISC_PLATFORM_RECVOVERFLOW
+#endif
+
+#define ISC__IPADDR(x) ((isc_uint32_t)htonl((isc_uint32_t)(x)))
+
+#define ISC_IPADDR_ISMULTICAST(i) \
+ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
+ == ISC__IPADDR(0xe0000000))
+
+#define ISC_IPADDR_ISEXPERIMENTAL(i) \
+ (((isc_uint32_t)(i) & ISC__IPADDR(0xf0000000)) \
+ == ISC__IPADDR(0xf0000000))
+
+/*
+ * Fix the FD_SET and FD_CLR Macros to properly cast
+ */
+#undef FD_CLR
+#define FD_CLR(fd, set) do { \
+ u_int __i; \
+ for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
+ if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET) fd) { \
+ while (__i < ((fd_set FAR *)(set))->fd_count-1) { \
+ ((fd_set FAR *)(set))->fd_array[__i] = \
+ ((fd_set FAR *)(set))->fd_array[__i+1]; \
+ __i++; \
+ } \
+ ((fd_set FAR *)(set))->fd_count--; \
+ break; \
+ } \
+ } \
+} while (0)
+
+#undef FD_SET
+#define FD_SET(fd, set) do { \
+ u_int __i; \
+ for (__i = 0; __i < ((fd_set FAR *)(set))->fd_count; __i++) { \
+ if (((fd_set FAR *)(set))->fd_array[__i] == (SOCKET)(fd)) { \
+ break; \
+ } \
+ } \
+ if (__i == ((fd_set FAR *)(set))->fd_count) { \
+ if (((fd_set FAR *)(set))->fd_count < FD_SETSIZE) { \
+ ((fd_set FAR *)(set))->fd_array[__i] = (SOCKET)(fd); \
+ ((fd_set FAR *)(set))->fd_count++; \
+ } \
+ } \
+} while (0)
+
+/*
+ * Windows Sockets errors redefined as regular Berkeley error constants.
+ * These are usually commented out in Windows NT to avoid conflicts with errno.h.
+ * Use the WSA constants instead.
+ * Starting with VC9 (VC++ 2010) many of these are defined incompatibly
+ * by errno.h -- #undef the conflicting values, which are not relevant to
+ * Win32.
+ */
+
+#undef EWOULDBLOCK
+#define EWOULDBLOCK WSAEWOULDBLOCK
+#undef EINPROGRESS
+#define EINPROGRESS WSAEINPROGRESS
+#undef EALREADY
+#define EALREADY WSAEALREADY
+#undef ENOTSOCK
+#define ENOTSOCK WSAENOTSOCK
+#undef EDESTADDRREQ
+#define EDESTADDRREQ WSAEDESTADDRREQ
+#undef EMSGSIZE
+#define EMSGSIZE WSAEMSGSIZE
+#undef EPROTOTYPE
+#define EPROTOTYPE WSAEPROTOTYPE
+#undef ENOPROTOOPT
+#define ENOPROTOOPT WSAENOPROTOOPT
+#undef EPROTONOSUPPORT
+#define EPROTONOSUPPORT WSAEPROTONOSUPPORT
+#define ESOCKTNOSUPPORT WSAESOCKTNOSUPPORT
+#undef EOPNOTSUPP
+#define EOPNOTSUPP WSAEOPNOTSUPP
+#define EPFNOSUPPORT WSAEPFNOSUPPORT
+#undef EAFNOSUPPORT
+#define EAFNOSUPPORT WSAEAFNOSUPPORT
+#undef EADDRINUSE
+#define EADDRINUSE WSAEADDRINUSE
+#undef EADDRNOTAVAIL
+#define EADDRNOTAVAIL WSAEADDRNOTAVAIL
+#undef ENETDOWN
+#define ENETDOWN WSAENETDOWN
+#undef ENETUNREACH
+#define ENETUNREACH WSAENETUNREACH
+#undef ENETRESET
+#define ENETRESET WSAENETRESET
+#undef ECONNABORTED
+#define ECONNABORTED WSAECONNABORTED
+#undef ECONNRESET
+#define ECONNRESET WSAECONNRESET
+#undef ENOBUFS
+#define ENOBUFS WSAENOBUFS
+#undef EISCONN
+#define EISCONN WSAEISCONN
+#undef ENOTCONN
+#define ENOTCONN WSAENOTCONN
+#define ESHUTDOWN WSAESHUTDOWN
+#define ETOOMANYREFS WSAETOOMANYREFS
+#undef ETIMEDOUT
+#define ETIMEDOUT WSAETIMEDOUT
+#undef ECONNREFUSED
+#define ECONNREFUSED WSAECONNREFUSED
+#undef ELOOP
+#define ELOOP WSAELOOP
+#define EHOSTDOWN WSAEHOSTDOWN
+#undef EHOSTUNREACH
+#define EHOSTUNREACH WSAEHOSTUNREACH
+#define EPROCLIM WSAEPROCLIM
+#define EUSERS WSAEUSERS
+#define EDQUOT WSAEDQUOT
+#define ESTALE WSAESTALE
+#define EREMOTE WSAEREMOTE
+
+
+/***
+ *** Functions.
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_net_probeipv4(void);
+/*
+ * Check if the system's kernel supports IPv4.
+ *
+ * Returns:
+ *
+ * ISC_R_SUCCESS IPv4 is supported.
+ * ISC_R_NOTFOUND IPv4 is not supported.
+ * ISC_R_DISABLED IPv4 is disabled.
+ * ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probeipv6(void);
+/*
+ * Check if the system's kernel supports IPv6.
+ *
+ * Returns:
+ *
+ * ISC_R_SUCCESS IPv6 is supported.
+ * ISC_R_NOTFOUND IPv6 is not supported.
+ * ISC_R_DISABLED IPv6 is disabled.
+ * ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probeunix(void);
+/*
+ * Check if UNIX domain sockets are supported.
+ *
+ * Returns:
+ *
+ * ISC_R_SUCCESS
+ * ISC_R_NOTFOUND
+ */
+
+isc_result_t
+isc_net_probe_ipv6only(void);
+/*
+ * Check if the system's kernel supports the IPV6_V6ONLY socket option.
+ *
+ * Returns:
+ *
+ * ISC_R_SUCCESS the option is supported for both TCP and UDP.
+ * ISC_R_NOTFOUND IPv6 itself or the option is not supported.
+ * ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_net_probe_ipv6pktinfo(void);
+/*
+ * Check if the system's kernel supports the IPV6_(RECV)PKTINFO socket option
+ * for UDP sockets.
+ *
+ * Returns:
+ *
+ * ISC_R_SUCCESS the option is supported.
+ * ISC_R_NOTFOUND IPv6 itself or the option is not supported.
+ * ISC_R_UNEXPECTED
+ */
+
+void
+isc_net_disableipv4(void);
+
+void
+isc_net_disableipv6(void);
+
+void
+isc_net_enableipv4(void);
+
+void
+isc_net_enableipv6(void);
+
+isc_result_t
+isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high);
+/*%<
+ * Returns system's default range of ephemeral UDP ports, if defined.
+ * If the range is not available or unknown, ISC_NET_PORTRANGELOW and
+ * ISC_NET_PORTRANGEHIGH will be returned.
+ *
+ * Requires:
+ *
+ *\li 'low' and 'high' must be non NULL.
+ *
+ * Returns:
+ *
+ *\li *low and *high will be the ports specifying the low and high ends of
+ * the range.
+ */
+
+#ifdef ISC_PLATFORM_NEEDNTOP
+const char *
+isc_net_ntop(int af, const void *src, char *dst, size_t size);
+#define inet_ntop isc_net_ntop
+#endif
+
+#ifdef ISC_PLATFORM_NEEDPTON
+int
+isc_net_pton(int af, const char *src, void *dst);
+#define inet_pton isc_net_pton
+#endif
+
+int
+isc_net_aton(const char *cp, struct in_addr *addr);
+#define inet_aton isc_net_aton
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NET_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/offset.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/offset.h
new file mode 100644
index 000000000000..f22fdce0a171
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/offset.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: offset.h,v 1.6 2007/06/19 23:47:20 tbox Exp $ */
+
+#ifndef ISC_OFFSET_H
+#define ISC_OFFSET_H 1
+
+/*
+ * File offsets are operating-system dependent.
+ */
+#include <limits.h> /* Required for CHAR_BIT. */
+#include <sys/types.h>
+
+typedef _off_t isc_offset_t;
+
+/*
+ * POSIX says "Additionally, blkcnt_t and off_t are extended signed integral
+ * types", so the maximum value is all 1s except for the high bit.
+ * This definition is more complex than it really needs to be because it was
+ * crafted to keep both the SunOS 5.6 and the HP/UX 11 compilers quiet about
+ * integer overflow. For example, though this is equivalent to just left
+ * shifting 1 to the high bit and then inverting the bits, the SunOS compiler
+ * is unhappy about shifting a positive "1" to negative in a signed integer.
+ */
+#define ISC_OFFSET_MAXIMUM \
+ (~(((off_t)-1 >> (sizeof(off_t) * CHAR_BIT - 1)) \
+ << (sizeof(off_t) * CHAR_BIT - 1)))
+
+#endif /* ISC_OFFSET_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/once.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/once.h
new file mode 100644
index 000000000000..0dc1686e4484
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/once.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: once.h,v 1.9 2007/06/19 23:47:20 tbox Exp $ */
+
+#ifndef ISC_ONCE_H
+#define ISC_ONCE_H 1
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+ISC_LANG_BEGINDECLS
+
+typedef struct {
+ int status;
+ LONG counter;
+} isc_once_t;
+
+#define ISC_ONCE_INIT_NEEDED 0
+#define ISC_ONCE_INIT_DONE 1
+
+#define ISC_ONCE_INIT { ISC_ONCE_INIT_NEEDED, 1 }
+
+isc_result_t
+isc_once_do(isc_once_t *controller, void(*function)(void));
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ONCE_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/platform.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/platform.h
new file mode 100644
index 000000000000..94b8ba508141
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/platform.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2004, 2005, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: platform.h,v 1.19 2009/09/29 23:48:04 tbox Exp $ */
+
+#ifndef ISC_PLATFORM_H
+#define ISC_PLATFORM_H 1
+
+/*****
+ ***** Platform-dependent defines.
+ *****/
+
+#define ISC_PLATFORM_USETHREADS
+
+/***
+ *** Network.
+ ***/
+
+#if _MSC_VER > 1200
+#define ISC_PLATFORM_HAVEIPV6
+#define ISC_PLATFORM_HAVEIN6PKTINFO
+#define ISC_PLATFORM_HAVESCOPEID
+#endif
+#define ISC_PLATFORM_NEEDPORTT
+#undef MSG_TRUNC
+#define ISC_PLATFORM_NEEDNTOP
+#define ISC_PLATFORM_NEEDPTON
+
+#ifndef ISC_PLATFORM_QUADFORMAT
+#define ISC_PLATFORM_QUADFORMAT "I64"
+#endif
+
+#define ISC_PLATFORM_NEEDSTRSEP
+#define ISC_PLATFORM_NEEDSTRLCPY
+#define ISC_PLATFORM_NEEDSTRLCAT
+#define ISC_PLATFORM_NEEDSTRLCPY
+
+/*
+ * Used to control how extern data is linked; needed for Win32 platforms.
+ */
+#define ISC_PLATFORM_USEDECLSPEC 1
+
+/*
+ * Define this here for now as winsock2.h defines h_errno
+ * and we don't want to redeclare it.
+ */
+#define ISC_PLATFORM_NONSTDHERRNO
+
+/*
+ * Define if the platform has <sys/un.h>.
+ */
+#undef ISC_PLATFORM_HAVESYSUNH
+
+/*
+ * Defines for the noreturn attribute.
+ */
+#define ISC_PLATFORM_NORETURN_PRE __declspec(noreturn)
+#define ISC_PLATFORM_NORETURN_POST
+
+/*
+ * Set up a macro for importing and exporting from the DLL
+ *
+ * To build static libraries on win32, #define ISC_STATIC_WIN
+ */
+#ifndef ISC_STATIC_WIN
+#define ISC_DLLEXP __declspec(dllexport)
+#define ISC_DLLIMP __declspec(dllimport)
+#else
+#define ISC_DLLEXP
+#define ISC_DLLIMP
+#endif
+
+#ifdef LIBISC_EXPORTS
+#define LIBISC_EXTERNAL_DATA ISC_DLLEXP
+#else
+#define LIBISC_EXTERNAL_DATA ISC_DLLIMP
+#endif
+
+#ifdef LIBISCCFG_EXPORTS
+#define LIBISCCFG_EXTERNAL_DATA ISC_DLLEXP
+#else
+#define LIBISCCFG_EXTERNAL_DATA ISC_DLLIMP
+#endif
+
+#ifdef LIBISCCC_EXPORTS
+#define LIBISCCC_EXTERNAL_DATA ISC_DLLEXP
+#else
+#define LIBISCCC_EXTERNAL_DATA ISC_DLLIMP
+#endif
+
+#ifdef LIBDNS_EXPORTS
+#define LIBDNS_EXTERNAL_DATA ISC_DLLEXP
+#else
+#define LIBDNS_EXTERNAL_DATA ISC_DLLIMP
+#endif
+
+#ifdef LIBBIND9_EXPORTS
+#define LIBBIND9_EXTERNAL_DATA ISC_DLLEXP
+#else
+#define LIBBIND9_EXTERNAL_DATA ISC_DLLIMP
+#endif
+
+#endif /* ISC_PLATFORM_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/stat.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/stat.h
new file mode 100644
index 000000000000..f95e3b0dd99c
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/stat.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: stat.h,v 1.9 2009/10/01 23:48:08 tbox Exp $ */
+
+#ifndef ISC_STAT_H
+#define ISC_STAT_H 1
+
+#include <sys/stat.h>
+
+/* open() under unix allows setting of read/write permissions
+ * at the owner, group and other levels. These don't exist in NT
+ * We'll just map them all to the NT equivalent
+ */
+
+#define S_IREAD _S_IREAD /* read permission, owner */
+#define S_IWRITE _S_IWRITE /* write permission, owner */
+#define S_IEXEC _S_IEXEC /* execute/search permission, owner */
+#define S_IRUSR _S_IREAD /* Owner read permission */
+#define S_IWUSR _S_IWRITE /* Owner write permission */
+#define S_IRGRP _S_IREAD /* Group read permission */
+#define S_IWGRP _S_IWRITE /* Group write permission */
+#define S_IROTH _S_IREAD /* Other read permission */
+#define S_IWOTH _S_IWRITE /* Other write permission */
+
+#ifndef S_IFMT
+# define S_IFMT _S_IFMT
+#endif
+#ifndef S_IFDIR
+# define S_IFDIR _S_IFDIR
+#endif
+#ifndef S_IFCHR
+# define S_IFCHR _S_IFCHR
+#endif
+#ifndef S_IFREG
+# define S_IFREG _S_IFREG
+#endif
+
+#ifndef S_ISDIR
+# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+#endif
+#ifndef S_ISREG
+# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
+
+#define O_RDONLY _O_RDONLY
+#define O_WRONLY _O_WRONLY
+#define O_RDWR _O_RDWR
+#define O_APPEND _O_APPEND
+#define O_CREAT _O_CREAT
+#define O_TRUNC _O_TRUNC
+#define O_EXCL _O_EXCL
+
+#endif /* ISC_STAT_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/stdtime.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/stdtime.h
new file mode 100644
index 000000000000..abbbc16c1d69
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/stdtime.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#ifndef ISC_STDTIME_H
+#define ISC_STDTIME_H 1
+
+#include <isc/lang.h>
+#include <isc/int.h>
+
+/*
+ * It's public information that 'isc_stdtime_t' is an unsigned integral type.
+ * Applications that want maximum portability should not assume anything
+ * about its size.
+ */
+typedef isc_uint32_t isc_stdtime_t;
+
+/* but this flag helps... */
+#define STDTIME_ON_32BITS 1
+
+/*
+ * isc_stdtime32_t is a 32-bit version of isc_stdtime_t. A variable of this
+ * type should only be used as an opaque integer (e.g.,) to compare two
+ * time values.
+ */
+typedef isc_uint32_t isc_stdtime32_t;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_stdtime_get(isc_stdtime_t *t);
+/*
+ * Set 't' to the number of seconds since 00:00:00 UTC, January 1, 1970.
+ *
+ * Requires:
+ *
+ * 't' is a valid pointer.
+ */
+
+#define isc_stdtime_convert32(t, t32p) (*(t32p) = t)
+/*
+ * Convert the standard time to its 32-bit version.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STDTIME_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/strerror.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/strerror.h
new file mode 100644
index 000000000000..38d2ef2b45e9
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/strerror.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: strerror.h,v 1.5 2007/06/19 23:47:20 tbox Exp $ */
+
+#ifndef ISC_STRERROR_H
+#define ISC_STRERROR_H
+
+#include <sys/types.h>
+
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+#define ISC_STRERRORSIZE 128
+
+/*
+ * Provide a thread safe wrapper to strerrror().
+ *
+ * Requires:
+ * 'buf' to be non NULL.
+ */
+void
+isc__strerror(int num, char *buf, size_t bufsize);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_STRERROR_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/thread.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/thread.h
new file mode 100644
index 000000000000..2eb923b2e61b
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/thread.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2004, 2005, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: thread.h,v 1.25 2009/09/29 04:37:08 marka Exp $ */
+
+#ifndef ISC_THREAD_H
+#define ISC_THREAD_H 1
+
+#include <windows.h>
+
+#include <isc/lang.h>
+#include <isc/result.h>
+
+/*
+ * Inlines to help with wait retrun checking
+ */
+
+/* check handle for NULL and INVALID_HANDLE */
+inline BOOL IsValidHandle( HANDLE hHandle) {
+ return ((hHandle != NULL) && (hHandle != INVALID_HANDLE_VALUE));
+}
+
+/* validate wait return codes... */
+inline BOOL WaitSucceeded( DWORD dwWaitResult, DWORD dwHandleCount) {
+ return ((dwWaitResult >= WAIT_OBJECT_0) &&
+ (dwWaitResult < WAIT_OBJECT_0 + dwHandleCount));
+}
+
+inline BOOL WaitAbandoned( DWORD dwWaitResult, DWORD dwHandleCount) {
+ return ((dwWaitResult >= WAIT_ABANDONED_0) &&
+ (dwWaitResult < WAIT_ABANDONED_0 + dwHandleCount));
+}
+
+inline BOOL WaitTimeout( DWORD dwWaitResult) {
+ return (dwWaitResult == WAIT_TIMEOUT);
+}
+
+inline BOOL WaitFailed( DWORD dwWaitResult) {
+ return (dwWaitResult == WAIT_FAILED);
+}
+
+/* compute object indices for waits... */
+inline DWORD WaitSucceededIndex( DWORD dwWaitResult) {
+ return (dwWaitResult - WAIT_OBJECT_0);
+}
+
+inline DWORD WaitAbandonedIndex( DWORD dwWaitResult) {
+ return (dwWaitResult - WAIT_ABANDONED_0);
+}
+
+
+
+typedef HANDLE isc_thread_t;
+typedef DWORD isc_threadresult_t;
+typedef void * isc_threadarg_t;
+typedef isc_threadresult_t (WINAPI *isc_threadfunc_t)(isc_threadarg_t);
+typedef DWORD isc_thread_key_t;
+
+#define isc_thread_self (unsigned long)GetCurrentThreadId
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_thread_create(isc_threadfunc_t, isc_threadarg_t, isc_thread_t *);
+
+isc_result_t
+isc_thread_join(isc_thread_t, isc_threadresult_t *);
+
+void
+isc_thread_setconcurrency(unsigned int level);
+
+int
+isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *));
+
+int
+isc_thread_key_delete(isc_thread_key_t key);
+
+void *
+isc_thread_key_getspecific(isc_thread_key_t);
+
+int
+isc_thread_key_setspecific(isc_thread_key_t key, void *value);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_THREAD_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/time.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/time.h
new file mode 100644
index 000000000000..8ffb24b11428
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/time.h
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2004, 2006-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: time.h,v 1.35 2009/01/05 23:47:54 tbox Exp $ */
+
+#ifndef ISC_TIME_H
+#define ISC_TIME_H 1
+
+#include <windows.h>
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/***
+ *** Intervals
+ ***/
+
+/*
+ * The contents of this structure are private, and MUST NOT be accessed
+ * directly by callers.
+ *
+ * The contents are exposed only to allow callers to avoid dynamic allocation.
+ */
+struct isc_interval {
+ isc_int64_t interval;
+};
+
+LIBISC_EXTERNAL_DATA extern isc_interval_t *isc_interval_zero;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_interval_set(isc_interval_t *i,
+ unsigned int seconds, unsigned int nanoseconds);
+/*
+ * Set 'i' to a value representing an interval of 'seconds' seconds and
+ * 'nanoseconds' nanoseconds, suitable for use in isc_time_add() and
+ * isc_time_subtract().
+ *
+ * Requires:
+ *
+ * 't' is a valid pointer.
+ * nanoseconds < 1000000000.
+ */
+
+isc_boolean_t
+isc_interval_iszero(const isc_interval_t *i);
+/*
+ * Returns ISC_TRUE iff. 'i' is the zero interval.
+ *
+ * Requires:
+ *
+ * 'i' is a valid pointer.
+ */
+
+/***
+ *** Absolute Times
+ ***/
+
+/*
+ * The contents of this structure are private, and MUST NOT be accessed
+ * directly by callers.
+ *
+ * The contents are exposed only to allow callers to avoid dynamic allocation.
+ */
+
+struct isc_time {
+ FILETIME absolute;
+};
+
+LIBISC_EXTERNAL_DATA extern isc_time_t *isc_time_epoch;
+
+void
+isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds);
+/*%<
+ * Set 't' to a value which represents the given number of seconds and
+ * nanoseconds since 00:00:00 January 1, 1970, UTC.
+ *
+ * Requires:
+ *\li 't' is a valid pointer.
+ *\li nanoseconds < 1000000000.
+ */
+
+void
+isc_time_settoepoch(isc_time_t *t);
+/*
+ * Set 't' to the time of the epoch.
+ *
+ * Notes:
+ * The date of the epoch is platform-dependent.
+ *
+ * Requires:
+ *
+ * 't' is a valid pointer.
+ */
+
+isc_boolean_t
+isc_time_isepoch(const isc_time_t *t);
+/*
+ * Returns ISC_TRUE iff. 't' is the epoch ("time zero").
+ *
+ * Requires:
+ *
+ * 't' is a valid pointer.
+ */
+
+isc_result_t
+isc_time_now(isc_time_t *t);
+/*
+ * Set 't' to the current absolute time.
+ *
+ * Requires:
+ *
+ * 't' is a valid pointer.
+ *
+ * Returns:
+ *
+ * Success
+ * Unexpected error
+ * Getting the time from the system failed.
+ * Out of range
+ * The time from the system is too large to be represented
+ * in the current definition of isc_time_t.
+ */
+
+isc_result_t
+isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i);
+/*
+ * Set *t to the current absolute time + i.
+ *
+ * Note:
+ * This call is equivalent to:
+ *
+ * isc_time_now(t);
+ * isc_time_add(t, i, t);
+ *
+ * Requires:
+ *
+ * 't' and 'i' are valid pointers.
+ *
+ * Returns:
+ *
+ * Success
+ * Unexpected error
+ * Getting the time from the system failed.
+ * Out of range
+ * The interval added to the time from the system is too large to
+ * be represented in the current definition of isc_time_t.
+ */
+
+int
+isc_time_compare(const isc_time_t *t1, const isc_time_t *t2);
+/*
+ * Compare the times referenced by 't1' and 't2'
+ *
+ * Requires:
+ *
+ * 't1' and 't2' are valid pointers.
+ *
+ * Returns:
+ *
+ * -1 t1 < t2 (comparing times, not pointers)
+ * 0 t1 = t2
+ * 1 t1 > t2
+ */
+
+isc_result_t
+isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result);
+/*
+ * Add 'i' to 't', storing the result in 'result'.
+ *
+ * Requires:
+ *
+ * 't', 'i', and 'result' are valid pointers.
+ *
+ * Returns:
+ * Success
+ * Out of range
+ * The interval added to the time is too large to
+ * be represented in the current definition of isc_time_t.
+ */
+
+isc_result_t
+isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
+ isc_time_t *result);
+/*
+ * Subtract 'i' from 't', storing the result in 'result'.
+ *
+ * Requires:
+ *
+ * 't', 'i', and 'result' are valid pointers.
+ *
+ * Returns:
+ * Success
+ * Out of range
+ * The interval is larger than the time since the epoch.
+ */
+
+isc_uint64_t
+isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2);
+/*
+ * Find the difference in milliseconds between time t1 and time t2.
+ * t2 is the subtrahend of t1; ie, difference = t1 - t2.
+ *
+ * Requires:
+ *
+ * 't1' and 't2' are valid pointers.
+ *
+ * Returns:
+ * The difference of t1 - t2, or 0 if t1 <= t2.
+ */
+
+isc_uint32_t
+isc_time_nanoseconds(const isc_time_t *t);
+/*
+ * Return the number of nanoseconds stored in a time structure.
+ *
+ * Notes:
+ * This is the number of nanoseconds in excess of the number
+ * of seconds since the epoch; it will always be less than one
+ * full second.
+ *
+ * Requires:
+ * 't' is a valid pointer.
+ *
+ * Ensures:
+ * The returned value is less than 1*10^9.
+ */
+
+void
+isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len);
+/*
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using a format like "30-Aug-2000 04:06:47.997" and the local time zone.
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ * 'len' > 0
+ * 'buf' points to an array of at least len chars
+ *
+ */
+
+void
+isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len);
+/*
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using a format like "Mon, 30 Aug 2000 04:06:47 GMT"
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ * 'len' > 0
+ * 'buf' points to an array of at least len chars
+ *
+ */
+
+void
+isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len);
+/*%<
+ * Format the time 't' into the buffer 'buf' of length 'len',
+ * using the ISO8601 format: "yyyy-mm-ddThh:mm:ssZ"
+ * If the text does not fit in the buffer, the result is indeterminate,
+ * but is always guaranteed to be null terminated.
+ *
+ * Requires:
+ *\li 'len' > 0
+ *\li 'buf' points to an array of at least len chars
+ *
+ */
+
+isc_uint32_t
+isc_time_seconds(const isc_time_t *t);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TIME_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/include/isc/win32os.h b/contrib/ntp/libntp/lib/isc/win32/include/isc/win32os.h
new file mode 100644
index 000000000000..bd4039361913
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/include/isc/win32os.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2004, 2007, 2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: win32os.h,v 1.7 2009/06/25 23:48:02 tbox Exp $ */
+
+#ifndef ISC_WIN32OS_H
+#define ISC_WIN32OS_H 1
+
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+/*
+ * Return the number of CPUs available on the system, or 1 if this cannot
+ * be determined.
+ */
+
+unsigned int
+isc_win32os_majorversion(void);
+/*
+ * Major Version of the O/S.
+ */
+
+unsigned int
+isc_win32os_minorversion(void);
+/*
+ * Minor Version of the O/S.
+ */
+
+unsigned int
+isc_win32os_servicepackmajor(void);
+/*
+ * Major Version of the Service Pack for O/S.
+ */
+
+unsigned int
+isc_win32os_servicepackminor(void);
+/*
+ * Minor Version of the Service Pack for O/S.
+ */
+
+int
+isc_win32os_versioncheck(unsigned int major, unsigned int minor,
+ unsigned int updatemajor, unsigned int updateminor);
+
+/*
+ * Checks the current version of the operating system with the
+ * supplied version information.
+ * Returns:
+ * -1 if less than the version information supplied
+ * 0 if equal to all of the version information supplied
+ * +1 if greater than the version information supplied
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_WIN32OS_H */
diff --git a/contrib/ntp/libntp/lib/isc/win32/interfaceiter.c b/contrib/ntp/libntp/lib/isc/win32/interfaceiter.c
new file mode 100644
index 000000000000..af52788f231c
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/interfaceiter.c
@@ -0,0 +1,807 @@
+/*
+ * Copyright (C) 2004, 2007-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: interfaceiter.c,v 1.15 2009/01/18 23:48:14 tbox Exp $ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <gaa_compat.h>
+
+#include <isc/interfaceiter.h>
+#include <isc/mem.h>
+#include <isc/result.h>
+#include <isc/string.h>
+#include <isc/strerror.h>
+#include <isc/types.h>
+#include <isc/util.h>
+#include <isc/win32os.h>
+
+void InitSockets(void);
+
+
+#define IFITER_MAGIC 0x49464954U /* IFIT. */
+#define VALID_IFITER(t) ((t) != NULL && (t)->magic == IFITER_MAGIC)
+
+struct isc_interfaceiter {
+ unsigned int magic; /* Magic number. */
+ /* common fields */
+ isc_mem_t *mctx;
+ isc_interface_t current; /* Current interface data. */
+ isc_result_t result; /* Last result code. */
+ /* fields used if GetAdaptersAddresses is available at runtime */
+ IP_ADAPTER_ADDRESSES * ipaa; /* GAA() result buffer */
+ ULONG ipaasize; /* Bytes allocated */
+ IP_ADAPTER_ADDRESSES * ipaaCur; /* enumeration position */
+ IP_ADAPTER_UNICAST_ADDRESS *ipuaCur; /* enumeration subposition */
+ /* fields used for the older address enumeration ioctls */
+ SOCKET socket;
+ INTERFACE_INFO IFData; /* Current Interface Info */
+ int numIF; /* Current Interface count */
+ int v4IF; /* Number of IPv4 Interfaces */
+ INTERFACE_INFO *buf4; /* Buffer for WSAIoctl data. */
+ unsigned int buf4size; /* Bytes allocated. */
+ INTERFACE_INFO *pos4; /* Current offset in IF List */
+ SOCKET_ADDRESS_LIST *buf6;
+ unsigned int buf6size; /* Bytes allocated. */
+ unsigned int pos6; /* buf6 index, counts down */
+ struct in6_addr loop__1; /* ::1 node-scope localhost */
+ struct in6_addr loopfe80__1; /* fe80::1 link-scope localhost */
+};
+
+typedef ULONG (WINAPI *PGETADAPTERSADDRESSES)(
+ ULONG Family,
+ ULONG Flags,
+ PVOID Reserved,
+ PIP_ADAPTER_ADDRESSES AdapterAddresses,
+ PULONG SizePointer
+);
+
+static isc_boolean_t use_GAA;
+static isc_boolean_t use_GAA_determined;
+static HMODULE hmod_iphlpapi;
+static PGETADAPTERSADDRESSES pGAA;
+
+
+/*
+ * Size of buffer for SIO_GET_INTERFACE_LIST, in number of interfaces.
+ * We assume no sane system will have more than than 1K of IP addresses on
+ * all of its adapters.
+ */
+#define IFCONF_SIZE_INITIAL 16
+#define IFCONF_SIZE_INCREMENT 64
+#define IFCONF_SIZE_MAX 1040
+
+
+/* Common utility functions */
+
+/*
+ * Windows always provides 255.255.255.255 as the the broadcast
+ * address. ntpd needs to know the broadcast address which will target
+ * only that network interface, not all. Reconstruct it from the
+ * address and mask.
+ */
+static void
+get_broadcastaddr(isc_netaddr_t *bcastaddr, isc_netaddr_t *addr, isc_netaddr_t *netmask) {
+
+ isc_uint32_t * b;
+ isc_uint32_t a, n;
+
+ b = (isc_uint32_t *)&bcastaddr->type.in;
+ a = *(isc_uint32_t *)&addr->type.in;
+ n = *(isc_uint32_t *)&netmask->type.in;
+
+ *b = a | ~n;
+}
+
+isc_result_t
+isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) {
+ char strbuf[ISC_STRERRORSIZE];
+ isc_interfaceiter_t *iter;
+ isc_result_t result;
+ unsigned int major;
+ unsigned int minor;
+ unsigned int spmajor;
+ ULONG err;
+ int tries;
+ int error;
+ unsigned long bytesReturned = 0;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(iterp != NULL);
+ REQUIRE(*iterp == NULL);
+
+ iter = isc_mem_get(mctx, sizeof(*iter));
+ if (iter == NULL)
+ return (ISC_R_NOMEMORY);
+
+ InitSockets();
+
+ iter->mctx = mctx;
+ iter->ipaa = NULL;
+ iter->buf4 = NULL;
+ iter->buf6 = NULL;
+ iter->pos4 = NULL;
+ iter->ipaaCur = NULL;
+ iter->ipuaCur = NULL;
+ iter->ipaasize = 0;
+ iter->pos6 = 0;
+ iter->buf6size = 0;
+ iter->buf4size = 0;
+ iter->result = ISC_R_FAILURE;
+ iter->numIF = 0;
+ iter->v4IF = 0;
+
+ /*
+ * Use GetAdaptersAddresses in preference to ioctls when running
+ * on Windows XP SP1 or later. Earlier GetAdaptersAddresses do
+ * not appear to provide enough information to associate unicast
+ * addresses with their prefixes.
+ */
+ if (!use_GAA_determined) {
+ major = isc_win32os_majorversion();
+ minor = isc_win32os_minorversion();
+ spmajor = isc_win32os_servicepackmajor();
+ if (major > 5 || (5 == major &&
+ (minor > 1 || (1 == minor && spmajor >= 1)))) {
+ if (NULL == hmod_iphlpapi)
+ hmod_iphlpapi = LoadLibrary("iphlpapi");
+ if (NULL != hmod_iphlpapi)
+ pGAA = (PGETADAPTERSADDRESSES)
+ GetProcAddress(
+ hmod_iphlpapi,
+ "GetAdaptersAddresses");
+ if (NULL != pGAA)
+ use_GAA = ISC_TRUE;
+ }
+ use_GAA_determined = ISC_TRUE;
+ }
+
+ if (!use_GAA)
+ goto use_ioctls;
+
+ iter->ipaasize = 16 * 1024;
+
+ for (tries = 0; tries < 5; tries++) {
+ iter->ipaa = isc_mem_reallocate(mctx, iter->ipaa,
+ iter->ipaasize);
+ if (NULL == iter->ipaa) {
+ result = ISC_R_NOMEMORY;
+ goto put_iter;
+ }
+ err = (*pGAA)(
+ AF_UNSPEC,
+ GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_SKIP_ANYCAST,
+ NULL,
+ iter->ipaa,
+ &iter->ipaasize);
+ if (NO_ERROR == err || ERROR_BUFFER_OVERFLOW != err)
+ break;
+ }
+
+ if (NO_ERROR != err) {
+ isc__strerror(err, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "GetAdaptersAddresses: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto gaa_failure;
+ }
+
+ iter->ipaaCur = iter->ipaa;
+ goto success;
+
+ use_ioctls:
+ /*
+ * Create an unbound datagram socket to do the
+ * SIO_GET_INTERFACE_LIST WSAIoctl on.
+ */
+ if ((iter->socket = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ error = WSAGetLastError();
+ if (error == WSAEAFNOSUPPORT)
+ goto inet6_only;
+ isc__strerror(error, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "making interface scan socket: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto put_iter;
+ }
+
+ /*
+ * Get the interface configuration, allocating more memory if
+ * necessary.
+ */
+ iter->buf4size = IFCONF_SIZE_INITIAL*sizeof(INTERFACE_INFO);
+
+ for (;;) {
+ iter->buf4 = isc_mem_get(mctx, iter->buf4size);
+ if (iter->buf4 == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto alloc_failure;
+ }
+
+ if (WSAIoctl(iter->socket, SIO_GET_INTERFACE_LIST,
+ 0, 0, iter->buf4, iter->buf4size,
+ &bytesReturned, 0, 0) == SOCKET_ERROR)
+ {
+ error = WSAGetLastError();
+ if (error != WSAEFAULT && error != WSAENOBUFS) {
+ errno = error;
+ isc__strerror(error, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "get interface configuration: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto ioctl_failure;
+ }
+ /*
+ * EINVAL. Retry with a bigger buffer.
+ */
+ } else {
+ /*
+ * The WSAIoctl succeeded.
+ * If the number of the returned bytes is the same
+ * as the buffer size, we will grow it just in
+ * case and retry.
+ */
+ if (bytesReturned > 0 &&
+ (bytesReturned < iter->buf4size))
+ break;
+ }
+ if (iter->buf4size >= IFCONF_SIZE_MAX*sizeof(INTERFACE_INFO)) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "get interface configuration: "
+ "maximum buffer size exceeded");
+ result = ISC_R_UNEXPECTED;
+ goto ioctl_failure;
+ }
+ isc_mem_put(mctx, iter->buf4, iter->buf4size);
+
+ iter->buf4size += IFCONF_SIZE_INCREMENT *
+ sizeof(INTERFACE_INFO);
+ }
+
+ /*
+ * A newly created iterator has an undefined position
+ * until isc_interfaceiter_first() is called.
+ */
+ iter->v4IF = bytesReturned/sizeof(INTERFACE_INFO);
+
+ /* We don't need the socket any more, so close it */
+ closesocket(iter->socket);
+
+ inet6_only:
+ /*
+ * Create an unbound datagram socket to do the
+ * SIO_ADDRESS_LIST_QUERY WSAIoctl on.
+ */
+ if ((iter->socket = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ error = WSAGetLastError();
+ if (error == WSAEAFNOSUPPORT)
+ goto success;
+ isc__strerror(error, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "making interface scan socket: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto put_iter;
+ }
+
+ /*
+ * Get the interface configuration, allocating more memory if
+ * necessary.
+ */
+ iter->buf6size = sizeof(SOCKET_ADDRESS_LIST) +
+ IFCONF_SIZE_INITIAL*sizeof(SOCKET_ADDRESS);
+
+ for (;;) {
+ iter->buf6 = isc_mem_get(mctx, iter->buf6size);
+ if (iter->buf6 == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto ioctl_failure;
+ }
+
+ if (WSAIoctl(iter->socket, SIO_ADDRESS_LIST_QUERY,
+ 0, 0, iter->buf6, iter->buf6size,
+ &bytesReturned, 0, 0) == SOCKET_ERROR)
+ {
+ error = WSAGetLastError();
+ if (error != WSAEFAULT && error != WSAENOBUFS) {
+ errno = error;
+ isc__strerror(error, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "sio address list query: %s",
+ strbuf);
+ result = ISC_R_UNEXPECTED;
+ goto ioctl6_failure;
+ }
+ /*
+ * EINVAL. Retry with a bigger buffer.
+ */
+ } else
+ break;
+
+ if (iter->buf6size >= IFCONF_SIZE_MAX*sizeof(SOCKET_ADDRESS)) {
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "get interface configuration: "
+ "maximum buffer size exceeded");
+ result = ISC_R_UNEXPECTED;
+ goto ioctl6_failure;
+ }
+ isc_mem_put(mctx, iter->buf6, iter->buf6size);
+
+ iter->buf6size += IFCONF_SIZE_INCREMENT *
+ sizeof(SOCKET_ADDRESS);
+ }
+
+ /*
+ * initialize loop__1 to [::1] and loopfe80__1 to [fe80::1].
+ * used by internal_current6().
+ */
+ memset(&iter->loop__1, 0, sizeof(iter->loop__1));
+ memset(&iter->loopfe80__1, 0, sizeof(iter->loopfe80__1));
+ iter->loop__1.s6_addr[15] = 1;
+ iter->loopfe80__1.s6_addr[15] = 1;
+ iter->loopfe80__1.s6_addr[0] = 0xfe;
+ iter->loopfe80__1.s6_addr[1] = 0x80;
+
+ closesocket(iter->socket);
+
+ success:
+ iter->magic = IFITER_MAGIC;
+ *iterp = iter;
+ return (ISC_R_SUCCESS);
+
+ gaa_failure:
+ isc_mem_put(mctx, iter->ipaa, iter->ipaasize);
+ goto put_iter;
+
+ ioctl6_failure:
+ isc_mem_put(mctx, iter->buf6, iter->buf6size);
+
+ ioctl_failure:
+ if (iter->buf4 != NULL)
+ isc_mem_put(mctx, iter->buf4, iter->buf4size);
+
+ alloc_failure:
+ if (iter->socket >= 0)
+ (void) closesocket(iter->socket);
+
+ put_iter:
+ isc_mem_put(mctx, iter, sizeof(*iter));
+ return (result);
+}
+
+static unsigned char
+GAA_find_prefix(isc_interfaceiter_t *iter) {
+ IP_ADAPTER_PREFIX * ipap;
+ IP_ADAPTER_PREFIX * ipap_match;
+ int match_len;
+ int max_len;
+ isc_netaddr_t target;
+ u_short af;
+ isc_netaddr_t pfx;
+ int pfx_len;
+ size_t nbytes;
+ unsigned char nbits;
+ unsigned char * pbits;
+ unsigned int octets;
+
+ match_len = 0;
+ ipap_match = NULL;
+ isc_netaddr_fromsockaddr(&target,
+ (isc_sockaddr_t *)iter->ipuaCur->Address.lpSockaddr);
+ af = (u_short)target.family;
+ INSIST(AF_INET == af || AF_INET6 == af);
+ max_len = (AF_INET6 == af) ? 128 : 32;
+ iter->current.netmask.family = af;
+ for (ipap = iter->ipaaCur->FirstPrefix;
+ ipap != NULL;
+ ipap = ipap->Next) {
+ if (ipap->Address.lpSockaddr->sa_family != af)
+ continue;
+ isc_netaddr_fromsockaddr(&pfx,
+ (isc_sockaddr_t *)ipap->Address.lpSockaddr);
+ pfx_len = ipap->PrefixLength;
+ INSIST(0 <= pfx_len && pfx_len <= max_len);
+ if (pfx_len > match_len && pfx_len < max_len &&
+ isc_netaddr_eqprefix(&target, &pfx, pfx_len)) {
+ ipap_match = ipap;
+ match_len = pfx_len;
+ }
+ }
+ if (NULL == ipap_match) {
+ /* presume all-ones mask */
+ if (AF_INET6 == af)
+ octets = sizeof(iter->current.netmask.type.in6);
+ else
+ octets = sizeof(iter->current.netmask.type.in);
+ memset(&iter->current.netmask.type, 0xFF, octets);
+ return (8 * (unsigned char)octets);
+ }
+ nbytes = match_len / 8;
+ nbits = match_len % 8;
+ memset(&iter->current.netmask.type.in6, 0xFF, nbytes);
+ pbits = (void *)&iter->current.netmask.type.in6;
+ pbits += nbytes;
+ *pbits |= 0xFF << (8 - nbits);
+ return ((unsigned char)match_len);
+}
+
+static isc_result_t
+internal_current_GAA(isc_interfaceiter_t *iter) {
+ IP_ADAPTER_ADDRESSES *adap;
+ IP_ADAPTER_UNICAST_ADDRESS *addr;
+ unsigned char prefix_len;
+
+ REQUIRE(iter->ipaaCur != NULL);
+ REQUIRE(iter->ipuaCur != NULL);
+ adap = iter->ipaaCur;
+ addr = iter->ipuaCur;
+ if (IpDadStatePreferred != addr->DadState)
+ return (ISC_R_IGNORE);
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = addr->Address.lpSockaddr->sa_family;
+ isc_netaddr_fromsockaddr(&iter->current.address,
+ (isc_sockaddr_t *)addr->Address.lpSockaddr);
+ if (AF_INET6 == iter->current.af)
+ iter->current.ifindex = adap->Ipv6IfIndex;
+ iter->current.name[0] = '\0';
+ WideCharToMultiByte(
+ CP_ACP,
+ 0,
+ adap->FriendlyName,
+ -1,
+ iter->current.name,
+ sizeof(iter->current.name),
+ NULL,
+ NULL);
+ iter->current.name[sizeof(iter->current.name) - 1] = '\0';
+ if (IfOperStatusUp == adap->OperStatus)
+ iter->current.flags |= INTERFACE_F_UP;
+ if (IF_TYPE_PPP == adap->IfType)
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+ else if (IF_TYPE_SOFTWARE_LOOPBACK == adap->IfType)
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+ if ((IP_ADAPTER_NO_MULTICAST & adap->Flags) == 0)
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+ if (IpSuffixOriginRandom == addr->SuffixOrigin)
+ iter->current.flags |= INTERFACE_F_PRIVACY;
+
+ prefix_len = GAA_find_prefix(iter);
+ /* I'm failing to see a broadcast flag via GAA */
+ if (AF_INET == iter->current.af && prefix_len < 32 &&
+ (INTERFACE_F_LOOPBACK & iter->current.flags) == 0) {
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+ get_broadcastaddr(&iter->current.broadcast,
+ &iter->current.address,
+ &iter->current.netmask);
+ }
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Get information about the current interface to iter->current.
+ * If successful, return ISC_R_SUCCESS.
+ * If the interface has an unsupported address family, or if
+ * some operation on it fails, return ISC_R_IGNORE to make
+ * the higher-level iterator code ignore it.
+ */
+
+static isc_result_t
+internal_current(isc_interfaceiter_t *iter) {
+ BOOL ifNamed = FALSE;
+ unsigned long flags;
+
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(iter->numIF >= 0);
+
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = AF_INET;
+
+ isc_netaddr_fromsockaddr(&iter->current.address,
+ (isc_sockaddr_t *)&(iter->IFData.iiAddress));
+
+ /*
+ * Get interface flags.
+ */
+
+ iter->current.flags = 0;
+ flags = iter->IFData.iiFlags;
+
+ if ((flags & IFF_UP) != 0)
+ iter->current.flags |= INTERFACE_F_UP;
+
+ if ((flags & IFF_BROADCAST) != 0)
+ iter->current.flags |= INTERFACE_F_BROADCAST;
+
+ if ((flags & IFF_MULTICAST) != 0)
+ iter->current.flags |= INTERFACE_F_MULTICAST;
+
+ if ((flags & IFF_POINTTOPOINT) != 0) {
+ iter->current.flags |= INTERFACE_F_POINTTOPOINT;
+ snprintf(iter->current.name, sizeof(iter->current.name),
+ "PPP %d", iter->numIF);
+ ifNamed = TRUE;
+ }
+
+ if ((flags & IFF_LOOPBACK) != 0) {
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+ snprintf(iter->current.name, sizeof(iter->current.name),
+ "v4loop %d", iter->numIF);
+ ifNamed = TRUE;
+ }
+
+ /*
+ * If the interface is point-to-point, get the destination address.
+ */
+ if ((iter->current.flags & INTERFACE_F_POINTTOPOINT) != 0)
+ isc_netaddr_fromsockaddr(&iter->current.dstaddress,
+ (isc_sockaddr_t *)&(iter->IFData.iiBroadcastAddress));
+
+ /*
+ * Get the network mask.
+ */
+ isc_netaddr_fromsockaddr(&iter->current.netmask,
+ (isc_sockaddr_t *)&(iter->IFData.iiNetmask));
+
+ /*
+ * If the interface is broadcast, get the broadcast address,
+ * based on the unicast address and network mask.
+ */
+ if ((iter->current.flags & INTERFACE_F_BROADCAST) != 0)
+ get_broadcastaddr(&iter->current.broadcast,
+ &iter->current.address,
+ &iter->current.netmask);
+
+ if (ifNamed == FALSE)
+ snprintf(iter->current.name, sizeof(iter->current.name),
+ "IPv4 %d", iter->numIF);
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+internal_current6(isc_interfaceiter_t *iter) {
+ BOOL ifNamed = FALSE;
+ struct sockaddr_in6 *psa6;
+ BOOL localhostSeen;
+ int i;
+
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(iter->pos6 >= 0);
+ REQUIRE(iter->buf6 != 0);
+
+ memset(&iter->current, 0, sizeof(iter->current));
+ iter->current.af = AF_INET6;
+
+ /*
+ * synthesize localhost ::1 before returning the rest, if ::1
+ * is not on the list.
+ */
+ if (iter->pos6 >= (unsigned)iter->buf6->iAddressCount) {
+ localhostSeen = FALSE;
+ for (i = 0; i < iter->buf6->iAddressCount; i++) {
+ psa6 = (struct sockaddr_in6 *)
+ iter->buf6->Address[i].lpSockaddr;
+ if (!memcmp(&iter->loop__1, &psa6->sin6_addr,
+ sizeof(iter->loop__1))) {
+ localhostSeen = TRUE;
+ break;
+ }
+ }
+ if (localhostSeen)
+ iter->pos6 = iter->buf6->iAddressCount - 1;
+ }
+
+ if (iter->pos6 < (unsigned)iter->buf6->iAddressCount) {
+ isc_netaddr_fromsockaddr(&iter->current.address,
+ (isc_sockaddr_t *)iter->buf6->Address[iter->pos6].lpSockaddr);
+ } else {
+ iter->current.address.family = AF_INET6;
+ memcpy(&iter->current.address.type.in6, &iter->loop__1,
+ sizeof(iter->current.address.type.in6));
+ }
+
+ /*
+ * Get interface flags.
+ */
+
+ iter->current.flags = INTERFACE_F_UP | INTERFACE_F_MULTICAST;
+
+ if (!memcmp(&iter->current.address.type.in6, &iter->loop__1,
+ sizeof(iter->current.address.type.in6)) ||
+ !memcmp(&iter->current.address.type.in6, &iter->loopfe80__1,
+ sizeof(iter->current.address.type.in6))) {
+
+ iter->current.flags |= INTERFACE_F_LOOPBACK;
+ snprintf(iter->current.name, sizeof(iter->current.name),
+ "v6loop %d",
+ iter->buf6->iAddressCount - iter->pos6);
+ ifNamed = TRUE;
+ }
+
+ if (ifNamed == FALSE)
+ snprintf(iter->current.name, sizeof(iter->current.name),
+ "IPv6 %d",
+ iter->buf6->iAddressCount - iter->pos6);
+
+ memset(iter->current.netmask.type.in6.s6_addr, 0xff,
+ sizeof(iter->current.netmask.type.in6.s6_addr));
+ iter->current.netmask.family = AF_INET6;
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+internal_next_GAA(isc_interfaceiter_t *iter) {
+ REQUIRE(use_GAA);
+ if (NULL == iter->ipaaCur)
+ return (ISC_R_NOMORE);
+ if (NULL == iter->ipuaCur)
+ iter->ipuaCur = iter->ipaaCur->FirstUnicastAddress;
+ else
+ iter->ipuaCur = iter->ipuaCur->Next;
+ while (NULL == iter->ipuaCur) {
+ iter->ipaaCur = iter->ipaaCur->Next;
+ if (NULL == iter->ipaaCur)
+ return (ISC_R_NOMORE);
+ iter->ipuaCur = iter->ipaaCur->FirstUnicastAddress;
+ }
+ return (ISC_R_SUCCESS);
+}
+
+/*
+ * Step the iterator to the next interface. Unlike
+ * isc_interfaceiter_next(), this may leave the iterator
+ * positioned on an interface that will ultimately
+ * be ignored. Return ISC_R_NOMORE if there are no more
+ * interfaces, otherwise ISC_R_SUCCESS.
+ */
+static isc_result_t
+internal_next(isc_interfaceiter_t *iter) {
+ if (iter->numIF >= iter->v4IF)
+ return (ISC_R_NOMORE);
+
+ /*
+ * The first one needs to be set up to point to the last
+ * Element of the array. Go to the end and back up
+ * Microsoft's implementation is peculiar for returning
+ * the list in reverse order
+ */
+
+ if (iter->numIF == 0)
+ iter->pos4 = (INTERFACE_INFO *)(iter->buf4 + (iter->v4IF));
+
+ iter->pos4--;
+ if (&(iter->pos4) < &(iter->buf4))
+ return (ISC_R_NOMORE);
+
+ memset(&(iter->IFData), 0, sizeof(INTERFACE_INFO));
+ memcpy(&(iter->IFData), iter->pos4, sizeof(INTERFACE_INFO));
+ iter->numIF++;
+
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+internal_next6(isc_interfaceiter_t *iter) {
+ if (iter->pos6 == 0)
+ return (ISC_R_NOMORE);
+ iter->pos6--;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_interfaceiter_current(isc_interfaceiter_t *iter,
+ isc_interface_t *ifdata) {
+ REQUIRE(iter->result == ISC_R_SUCCESS);
+ memcpy(ifdata, &iter->current, sizeof(*ifdata));
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_interfaceiter_first(isc_interfaceiter_t *iter) {
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(use_GAA_determined);
+ /*
+ * SIO_ADDRESS_LIST_QUERY (used to query IPv6 addresses)
+ * intentionally omits localhost addresses [::1] and [::fe80] in
+ * some cases. ntpd depends on enumerating [::1] to listen on
+ * it, and ntpq and ntpdc default to "localhost" as the target,
+ * so they will attempt to talk to [::1]:123 and fail. This
+ * means we need to synthesize ::1, which we will do first,
+ * hence iAddressCount + 1. internal_next6() will decrement
+ * it before the first use as an index, and internal_current6()
+ * will treat pos6 == iAddressCount as a sign to synthesize
+ * [::1] if needed.
+ */
+ if (!use_GAA && iter->buf6 != NULL)
+ iter->pos6 = iter->buf6->iAddressCount + 1;
+ iter->result = ISC_R_SUCCESS;
+ return (isc_interfaceiter_next(iter));
+}
+
+isc_result_t
+isc_interfaceiter_next(isc_interfaceiter_t *iter) {
+ isc_result_t result;
+
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(iter->result == ISC_R_SUCCESS);
+ REQUIRE(use_GAA_determined);
+
+ if (use_GAA) {
+ do {
+ result = internal_next_GAA(iter);
+ if (ISC_R_NOMORE == result)
+ goto set_result;
+ result = internal_current_GAA(iter);
+ } while (ISC_R_IGNORE == result);
+ goto set_result;
+ }
+
+ for (;;) {
+ result = internal_next(iter);
+ if (result == ISC_R_NOMORE) {
+ result = internal_next6(iter);
+ if (result != ISC_R_SUCCESS)
+ break;
+ result = internal_current6(iter);
+ if (result != ISC_R_IGNORE)
+ break;
+ } else if (result != ISC_R_SUCCESS)
+ break;
+ result = internal_current(iter);
+ if (result != ISC_R_IGNORE)
+ break;
+ }
+ set_result:
+ iter->result = result;
+ return (result);
+}
+
+void
+isc_interfaceiter_destroy(isc_interfaceiter_t **iterp) {
+ isc_interfaceiter_t *iter;
+
+ REQUIRE(iterp != NULL);
+ iter = *iterp;
+ REQUIRE(VALID_IFITER(iter));
+ REQUIRE(use_GAA_determined);
+
+ if (use_GAA) {
+ REQUIRE(NULL == iter->buf4);
+ REQUIRE(NULL == iter->buf4);
+ if (iter->ipaa != NULL)
+ isc_mem_put(iter->mctx, iter->ipaa, iter->ipaasize);
+ } else {
+ REQUIRE(NULL == iter->ipaa);
+ if (iter->buf4 != NULL)
+ isc_mem_put(iter->mctx, iter->buf4, iter->buf4size);
+ if (iter->buf6 != NULL)
+ isc_mem_put(iter->mctx, iter->buf6, iter->buf6size);
+ }
+
+ iter->magic = 0;
+ isc_mem_put(iter->mctx, iter, sizeof(*iter));
+ *iterp = NULL;
+}
diff --git a/contrib/ntp/libntp/lib/isc/win32/net.c b/contrib/ntp/libntp/lib/isc/win32/net.c
new file mode 100644
index 000000000000..53e143556721
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/net.c
@@ -0,0 +1,339 @@
+/*
+ * Copyright (C) 2004, 2005, 2007-2009, 2011, 2012 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id$ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <unistd.h>
+
+#include <isc/log.h>
+#include <isc/msgs.h>
+#include <isc/net.h>
+#include <isc/once.h>
+#include <isc/strerror.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+/*%
+ * Definitions about UDP port range specification. This is a total mess of
+ * portability variants: some use sysctl (but the sysctl names vary), some use
+ * system-specific interfaces, some have the same interface for IPv4 and IPv6,
+ * some separate them, etc...
+ */
+
+/*%
+ * The last resort defaults: use all non well known port space
+ */
+#ifndef ISC_NET_PORTRANGELOW
+#define ISC_NET_PORTRANGELOW 1024
+#endif /* ISC_NET_PORTRANGELOW */
+#ifndef ISC_NET_PORTRANGEHIGH
+#define ISC_NET_PORTRANGEHIGH 65535
+#endif /* ISC_NET_PORTRANGEHIGH */
+
+#if defined(ISC_PLATFORM_NEEDIN6ADDRANY)
+const struct in6_addr isc_net_in6addrany = IN6ADDR_ANY_INIT;
+#endif
+
+#if defined(ISC_PLATFORM_NEEDIN6ADDRLOOPBACK)
+const struct in6_addr isc_net_in6addrloop = IN6ADDR_LOOPBACK_INIT;
+#endif
+
+
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_once_t once_ipv6only = ISC_ONCE_INIT;
+static isc_once_t once_ipv6pktinfo = ISC_ONCE_INIT;
+static isc_result_t ipv4_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6only_result = ISC_R_NOTFOUND;
+static isc_result_t ipv6pktinfo_result = ISC_R_NOTFOUND;
+
+void InitSockets(void);
+
+static isc_result_t
+try_proto(int domain) {
+ SOCKET s;
+ char strbuf[ISC_STRERRORSIZE];
+ int errval;
+
+ s = socket(domain, SOCK_STREAM, IPPROTO_TCP);
+ if (s == INVALID_SOCKET) {
+ errval = WSAGetLastError();
+ switch (errval) {
+ case WSAEAFNOSUPPORT:
+ case WSAEPROTONOSUPPORT:
+ case WSAEINVAL:
+ return (ISC_R_NOTFOUND);
+ default:
+ isc__strerror(errval, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ return (ISC_R_UNEXPECTED);
+ }
+ }
+
+ closesocket(s);
+
+ return (ISC_R_SUCCESS);
+}
+
+static void
+initialize_action(void) {
+ InitSockets();
+ ipv4_result = try_proto(PF_INET);
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+#ifdef ISC_PLATFORM_HAVEIN6PKTINFO
+ ipv6_result = try_proto(PF_INET6);
+#endif
+#endif
+#endif
+}
+
+static void
+initialize(void) {
+ RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_net_probeipv4(void) {
+ initialize();
+ return (ipv4_result);
+}
+
+isc_result_t
+isc_net_probeipv6(void) {
+ initialize();
+ return (ipv6_result);
+}
+
+isc_result_t
+isc_net_probeunix(void) {
+ return (ISC_R_NOTFOUND);
+}
+
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+static void
+try_ipv6only(void) {
+#ifdef IPV6_V6ONLY
+ SOCKET s;
+ int on;
+ char strbuf[ISC_STRERRORSIZE];
+#endif
+ isc_result_t result;
+
+ result = isc_net_probeipv6();
+ if (result != ISC_R_SUCCESS) {
+ ipv6only_result = result;
+ return;
+ }
+
+#ifndef IPV6_V6ONLY
+ ipv6only_result = ISC_R_NOTFOUND;
+ return;
+#else
+ /* check for TCP sockets */
+ s = socket(PF_INET6, SOCK_STREAM, 0);
+ if (s == INVALID_SOCKET) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6only_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&on,
+ sizeof(on)) < 0) {
+ ipv6only_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ closesocket(s);
+
+ /* check for UDP sockets */
+ s = socket(PF_INET6, SOCK_DGRAM, 0);
+ if (s == INVALID_SOCKET) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6only_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&on,
+ sizeof(on)) < 0) {
+ ipv6only_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ ipv6only_result = ISC_R_SUCCESS;
+
+close:
+ closesocket(s);
+ return;
+#endif /* IPV6_V6ONLY */
+}
+
+static void
+initialize_ipv6only(void) {
+ RUNTIME_CHECK(isc_once_do(&once_ipv6only,
+ try_ipv6only) == ISC_R_SUCCESS);
+}
+
+static void
+try_ipv6pktinfo(void) {
+ SOCKET s;
+ int on;
+ char strbuf[ISC_STRERRORSIZE];
+ isc_result_t result;
+ int optname;
+
+ result = isc_net_probeipv6();
+ if (result != ISC_R_SUCCESS) {
+ ipv6pktinfo_result = result;
+ return;
+ }
+
+ /* we only use this for UDP sockets */
+ s = socket(PF_INET6, SOCK_DGRAM, IPPROTO_UDP);
+ if (s == INVALID_SOCKET) {
+ isc__strerror(errno, strbuf, sizeof(strbuf));
+ UNEXPECTED_ERROR(__FILE__, __LINE__,
+ "socket() %s: %s",
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED,
+ "failed"),
+ strbuf);
+ ipv6pktinfo_result = ISC_R_UNEXPECTED;
+ return;
+ }
+
+#ifdef IPV6_RECVPKTINFO
+ optname = IPV6_RECVPKTINFO;
+#else
+ optname = IPV6_PKTINFO;
+#endif
+ on = 1;
+ if (setsockopt(s, IPPROTO_IPV6, optname, (const char *) &on,
+ sizeof(on)) < 0) {
+ ipv6pktinfo_result = ISC_R_NOTFOUND;
+ goto close;
+ }
+
+ ipv6pktinfo_result = ISC_R_SUCCESS;
+
+close:
+ closesocket(s);
+ return;
+}
+
+static void
+initialize_ipv6pktinfo(void) {
+ RUNTIME_CHECK(isc_once_do(&once_ipv6pktinfo,
+ try_ipv6pktinfo) == ISC_R_SUCCESS);
+}
+#endif /* WANT_IPV6 */
+#endif /* ISC_PLATFORM_HAVEIPV6 */
+
+isc_result_t
+isc_net_probe_ipv6only(void) {
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+ initialize_ipv6only();
+#else
+ ipv6only_result = ISC_R_NOTFOUND;
+#endif
+#endif
+ return (ipv6only_result);
+}
+
+isc_result_t
+isc_net_probe_ipv6pktinfo(void) {
+#ifdef ISC_PLATFORM_HAVEIPV6
+#ifdef WANT_IPV6
+ initialize_ipv6pktinfo();
+#else
+ ipv6pktinfo_result = ISC_R_NOTFOUND;
+#endif
+#endif
+ return (ipv6pktinfo_result);
+}
+
+isc_result_t
+isc_net_getudpportrange(int af, in_port_t *low, in_port_t *high) {
+ int result = ISC_R_FAILURE;
+
+ REQUIRE(low != NULL && high != NULL);
+
+ UNUSED(af);
+
+ if (result != ISC_R_SUCCESS) {
+ *low = ISC_NET_PORTRANGELOW;
+ *high = ISC_NET_PORTRANGEHIGH;
+ }
+
+ return (ISC_R_SUCCESS); /* we currently never fail in this function */
+}
+
+void
+isc_net_disableipv4(void) {
+ initialize();
+ if (ipv4_result == ISC_R_SUCCESS)
+ ipv4_result = ISC_R_DISABLED;
+}
+
+void
+isc_net_disableipv6(void) {
+ initialize();
+ if (ipv6_result == ISC_R_SUCCESS)
+ ipv6_result = ISC_R_DISABLED;
+}
+
+void
+isc_net_enableipv4(void) {
+ initialize();
+ if (ipv4_result == ISC_R_DISABLED)
+ ipv4_result = ISC_R_SUCCESS;
+}
+
+void
+isc_net_enableipv6(void) {
+ initialize();
+ if (ipv6_result == ISC_R_DISABLED)
+ ipv6_result = ISC_R_SUCCESS;
+}
diff --git a/contrib/ntp/libntp/lib/isc/win32/once.c b/contrib/ntp/libntp/lib/isc/win32/once.c
new file mode 100644
index 000000000000..b5047762ad77
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/once.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: once.c,v 1.12 2007/06/18 23:47:49 tbox Exp $ */
+
+/* Principal Authors: DCL */
+
+#include <config.h>
+
+#include <windows.h>
+
+#include <isc/once.h>
+#include <isc/assertions.h>
+#include <isc/util.h>
+
+isc_result_t
+isc_once_do(isc_once_t *controller, void(*function)(void)) {
+ REQUIRE(controller != NULL && function != NULL);
+
+ if (controller->status == ISC_ONCE_INIT_NEEDED) {
+
+ if (InterlockedDecrement(&controller->counter) == 0) {
+ if (controller->status == ISC_ONCE_INIT_NEEDED) {
+ function();
+ controller->status = ISC_ONCE_INIT_DONE;
+ }
+ } else {
+ while (controller->status == ISC_ONCE_INIT_NEEDED) {
+ /*
+ * Sleep(0) indicates that this thread
+ * should be suspended to allow other
+ * waiting threads to execute.
+ */
+ Sleep(0);
+ }
+ }
+ }
+
+ return (ISC_R_SUCCESS);
+}
diff --git a/contrib/ntp/libntp/lib/isc/win32/stdtime.c b/contrib/ntp/libntp/lib/isc/win32/stdtime.c
new file mode 100644
index 000000000000..ca462513c213
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/stdtime.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: stdtime.c,v 1.12 2007/06/19 23:47:19 tbox Exp $ */
+
+#include <config.h>
+
+#include <time.h>
+
+#include <isc/assertions.h>
+#include <isc/stdtime.h>
+#include <isc/util.h>
+
+void
+isc_stdtime_get(isc_stdtime_t *t) {
+ /*
+ * Set 't' to the number of seconds past 00:00:00 UTC, January 1, 1970.
+ */
+
+ REQUIRE(t != NULL);
+
+ (void)time((time_t *)t);
+}
diff --git a/contrib/ntp/libntp/lib/isc/win32/strerror.c b/contrib/ntp/libntp/lib/isc/win32/strerror.c
new file mode 100644
index 000000000000..21bdad97778e
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/strerror.c
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001, 2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: strerror.c,v 1.8 2007/06/19 23:47:19 tbox Exp $ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <string.h>
+#include <winsock2.h>
+
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/print.h>
+#include <isc/strerror.h>
+#include <isc/util.h>
+
+#include "lib_strbuf.h"
+
+/*
+ * Forward declarations
+ */
+
+char *
+FormatError(int error);
+
+char *
+GetWSAErrorMessage(int errval);
+
+char *
+NTstrerror(int err, BOOL *bfreebuf);
+
+/*
+ * We need to do this this way for profiled locks.
+ */
+
+static isc_mutex_t isc_strerror_lock;
+static void init_lock(void) {
+ RUNTIME_CHECK(isc_mutex_init(&isc_strerror_lock) == ISC_R_SUCCESS);
+}
+
+/*
+ * This routine needs to free up any buffer allocated by FormatMessage
+ * if that routine gets used.
+ */
+
+void
+isc__strerror(int num, char *buf, size_t size) {
+ char *msg;
+ BOOL freebuf;
+ unsigned int unum = num;
+ static isc_once_t once = ISC_ONCE_INIT;
+
+ REQUIRE(buf != NULL);
+
+ RUNTIME_CHECK(isc_once_do(&once, init_lock) == ISC_R_SUCCESS);
+
+ LOCK(&isc_strerror_lock);
+ freebuf = FALSE;
+ msg = NTstrerror(num, &freebuf);
+ if (msg != NULL)
+ snprintf(buf, size, "%s", msg);
+ else
+ snprintf(buf, size, "Unknown error: %u", unum);
+ if(freebuf && msg != NULL) {
+ LocalFree(msg);
+ }
+ UNLOCK(&isc_strerror_lock);
+}
+
+/*
+ * Note this will cause a memory leak unless the memory allocated here
+ * is freed by calling LocalFree. isc__strerror does this before unlocking.
+ * This only gets called if there is a system type of error and will likely
+ * be an unusual event.
+ */
+char *
+FormatError(int error) {
+ char *lpMsgBuf = NULL;
+ char *pch;
+ const char boiler[] =
+ " For information about network troubleshooting, see Windows Help.";
+ size_t last;
+
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ (FORMAT_MESSAGE_MAX_WIDTH_MASK - 1),
+ NULL,
+ error,
+ /* Default language */
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR)(PVOID)&lpMsgBuf,
+ 0,
+ NULL);
+
+ /* remove useless boilerplate */
+ pch = strstr(lpMsgBuf, boiler);
+ if (pch != NULL) {
+ *pch = '\0';
+ }
+
+ /* strip any trailing CR/LF and spaces */
+ if (lpMsgBuf != NULL) {
+ last = strlen(lpMsgBuf);
+ if (last > 0) {
+ --last;
+ }
+ while ('\n' == lpMsgBuf[last] ||
+ '\r' == lpMsgBuf[last] ||
+ ' ' == lpMsgBuf[last]) {
+
+ lpMsgBuf[last] = '\0';
+ if (last > 0) {
+ --last;
+ }
+ }
+ }
+
+ return (lpMsgBuf);
+}
+
+/*
+ * This routine checks the error value and calls the WSA Windows Sockets
+ * Error message function GetWSAErrorMessage below if it's within that range
+ * since those messages are not available in the system error messages.
+ */
+char *
+NTstrerror(int err, BOOL *bfreebuf) {
+ char *retmsg = NULL;
+
+ *bfreebuf = FALSE;
+
+ /* Get the Winsock2 error messages */
+ /* DLH this may not be needed, FormatError/FormatMessage may handle Winsock error codes */
+ if (err >= WSABASEERR && err <= (WSABASEERR + 1999)) {
+ retmsg = GetWSAErrorMessage(err);
+ }
+ /*
+ * If it's not one of the standard Unix error codes,
+ * try a system error message
+ */
+ if (NULL == retmsg) {
+ if (err > _sys_nerr) {
+ *bfreebuf = TRUE;
+ retmsg = FormatError(err);
+ } else {
+ retmsg = lib_getbuf();
+ if (0 != strerror_s(retmsg, LIB_BUFLENGTH, err)) {
+ snprintf(retmsg, LIB_BUFLENGTH,
+ "Unknown error number %d/0x%x",
+ err, err);
+ }
+ }
+ }
+ return retmsg;
+}
+
+/*
+ * This is a replacement for perror
+ */
+void __cdecl
+NTperror(char *errmsg) {
+ /* Copy the error value first in case of other errors */
+ int errval = errno;
+ BOOL bfreebuf = FALSE;
+ char *msg;
+
+ msg = NTstrerror(errval, &bfreebuf);
+ fprintf(stderr, "%s: %s\n", errmsg, msg);
+ if(bfreebuf == TRUE) {
+ LocalFree(msg);
+ }
+
+}
+
+/*
+ * Return the error string related to Winsock2 errors.
+ * This function is necessary since FormatMessage knows nothing about them
+ * and there is no function to get them.
+ */
+char *
+GetWSAErrorMessage(int errval) {
+ char *msg;
+
+ switch (errval) {
+
+ case WSAEINTR:
+ msg = "Interrupted system call";
+ break;
+
+ case WSAEBADF:
+ msg = "Bad file number";
+ break;
+
+ case WSAEACCES:
+ msg = "Permission denied";
+ break;
+
+ case WSAEFAULT:
+ msg = "Bad address";
+ break;
+
+ case WSAEINVAL:
+ msg = "Invalid argument";
+ break;
+
+ case WSAEMFILE:
+ msg = "Too many open sockets";
+ break;
+
+ case WSAEWOULDBLOCK:
+ msg = "Operation would block";
+ break;
+
+ case WSAEINPROGRESS:
+ msg = "Operation now in progress";
+ break;
+
+ case WSAEALREADY:
+ msg = "Operation already in progress";
+ break;
+
+ case WSAENOTSOCK:
+ msg = "Socket operation on non-socket";
+ break;
+
+ case WSAEDESTADDRREQ:
+ msg = "Destination address required";
+ break;
+
+ case WSAEMSGSIZE:
+ msg = "Message too long";
+ break;
+
+ case WSAEPROTOTYPE:
+ msg = "Protocol wrong type for socket";
+ break;
+
+ case WSAENOPROTOOPT:
+ msg = "Bad protocol option";
+ break;
+
+ case WSAEPROTONOSUPPORT:
+ msg = "Protocol not supported";
+ break;
+
+ case WSAESOCKTNOSUPPORT:
+ msg = "Socket type not supported";
+ break;
+
+ case WSAEOPNOTSUPP:
+ msg = "Operation not supported on socket";
+ break;
+
+ case WSAEPFNOSUPPORT:
+ msg = "Protocol family not supported";
+ break;
+
+ case WSAEAFNOSUPPORT:
+ msg = "Address family not supported";
+ break;
+
+ case WSAEADDRINUSE:
+ msg = "Address already in use";
+ break;
+
+ case WSAEADDRNOTAVAIL:
+ msg = "Can't assign requested address";
+ break;
+
+ case WSAENETDOWN:
+ msg = "Network is down";
+ break;
+
+ case WSAENETUNREACH:
+ msg = "Network is unreachable";
+ break;
+
+ case WSAENETRESET:
+ msg = "Net connection reset";
+ break;
+
+ case WSAECONNABORTED:
+ msg = "Software caused connection abort";
+ break;
+
+ case WSAECONNRESET:
+ msg = "Connection reset by peer";
+ break;
+
+ case WSAENOBUFS:
+ msg = "No buffer space available";
+ break;
+
+ case WSAEISCONN:
+ msg = "Socket is already connected";
+ break;
+
+ case WSAENOTCONN:
+ msg = "Socket is not connected";
+ break;
+
+ case WSAESHUTDOWN:
+ msg = "Can't send after socket shutdown";
+ break;
+
+ case WSAETOOMANYREFS:
+ msg = "Too many references: can't splice";
+ break;
+
+ case WSAETIMEDOUT:
+ msg = "Connection timed out";
+ break;
+
+ case WSAECONNREFUSED:
+ msg = "Connection refused";
+ break;
+
+ case WSAELOOP:
+ msg = "Too many levels of symbolic links";
+ break;
+
+ case WSAENAMETOOLONG:
+ msg = "File name too long";
+ break;
+
+ case WSAEHOSTDOWN:
+ msg = "Host is down";
+ break;
+
+ case WSAEHOSTUNREACH:
+ msg = "No route to host";
+ break;
+
+ case WSAENOTEMPTY:
+ msg = "Directory not empty";
+ break;
+
+ case WSAEPROCLIM:
+ msg = "Too many processes";
+ break;
+
+ case WSAEUSERS:
+ msg = "Too many users";
+ break;
+
+ case WSAEDQUOT:
+ msg = "Disc quota exceeded";
+ break;
+
+ case WSAESTALE:
+ msg = "Stale NFS file handle";
+ break;
+
+ case WSAEREMOTE:
+ msg = "Too many levels of remote in path";
+ break;
+
+ case WSASYSNOTREADY:
+ msg = "Network system is unavailable";
+ break;
+
+ case WSAVERNOTSUPPORTED:
+ msg = "Winsock version out of range";
+ break;
+
+ case WSANOTINITIALISED:
+ msg = "WSAStartup not yet called";
+ break;
+
+ case WSAEDISCON:
+ msg = "Graceful shutdown in progress";
+ break;
+/*
+ case WSAHOST_NOT_FOUND:
+ msg = "Host not found";
+ break;
+
+ case WSANO_DATA:
+ msg = "No host data of that type was found";
+ break;
+*/
+ default:
+ msg = NULL;
+ break;
+ }
+ return (msg);
+}
+
+/*
+ * These error messages are more informative about CryptAPI Errors than the
+ * standard error messages
+ */
+
+char *
+GetCryptErrorMessage(int errval) {
+ char *msg;
+
+ switch (errval) {
+
+ case NTE_BAD_FLAGS:
+ msg = "The dwFlags parameter has an illegal value.";
+ break;
+ case NTE_BAD_KEYSET:
+ msg = "The Registry entry for the key container "
+ "could not be opened and may not exist.";
+ break;
+ case NTE_BAD_KEYSET_PARAM:
+ msg = "The pszContainer or pszProvider parameter "
+ "is set to an illegal value.";
+ break;
+ case NTE_BAD_PROV_TYPE:
+ msg = "The value of the dwProvType parameter is out "
+ "of range. All provider types must be from "
+ "1 to 999, inclusive.";
+ break;
+ case NTE_BAD_SIGNATURE:
+ msg = "The provider DLL signature did not verify "
+ "correctly. Either the DLL or the digital "
+ "signature has been tampered with.";
+ break;
+ case NTE_EXISTS:
+ msg = "The dwFlags parameter is CRYPT_NEWKEYSET, but the key"
+ " container already exists.";
+ break;
+ case NTE_KEYSET_ENTRY_BAD:
+ msg = "The Registry entry for the pszContainer key container "
+ "was found (in the HKEY_CURRENT_USER window), but is "
+ "corrupt. See the section System Administration for "
+ " etails about CryptoAPI's Registry usage.";
+ break;
+ case NTE_KEYSET_NOT_DEF:
+ msg = "No Registry entry exists in the HKEY_CURRENT_USER "
+ "window for the key container specified by "
+ "pszContainer.";
+ break;
+ case NTE_NO_MEMORY:
+ msg = "The CSP ran out of memory during the operation.";
+ break;
+ case NTE_PROV_DLL_NOT_FOUND:
+ msg = "The provider DLL file does not exist or is not on the "
+ "current path.";
+ break;
+ case NTE_PROV_TYPE_ENTRY_BAD:
+ msg = "The Registry entry for the provider type specified by "
+ "dwProvType is corrupt. This error may relate to "
+ "either the user default CSP list or the machine "
+ "default CSP list. See the section System "
+ "Administration for details about CryptoAPI's "
+ "Registry usage.";
+ break;
+ case NTE_PROV_TYPE_NO_MATCH:
+ msg = "The provider type specified by dwProvType does not "
+ "match the provider type found in the Registry. Note "
+ "that this error can only occur when pszProvider "
+ "specifies an actual CSP name.";
+ break;
+ case NTE_PROV_TYPE_NOT_DEF:
+ msg = "No Registry entry exists for the provider type "
+ "specified by dwProvType.";
+ break;
+ case NTE_PROVIDER_DLL_FAIL:
+ msg = "The provider DLL file could not be loaded, and "
+ "may not exist. If it exists, then the file is "
+ "not a valid DLL.";
+ break;
+ case NTE_SIGNATURE_FILE_BAD:
+ msg = "An error occurred while loading the DLL file image, "
+ "prior to verifying its signature.";
+ break;
+
+ default:
+ msg = NULL;
+ break;
+ }
+ return msg;
+}
+
diff --git a/contrib/ntp/libntp/lib/isc/win32/thread.c b/contrib/ntp/libntp/lib/isc/win32/thread.c
new file mode 100644
index 000000000000..85ffef1e7a6b
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/thread.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: thread.c,v 1.24 2007/06/19 23:47:19 tbox Exp $ */
+
+#include <config.h>
+
+#include <process.h>
+
+#include <isc/thread.h>
+
+isc_result_t
+isc_thread_create(isc_threadfunc_t start, isc_threadarg_t arg,
+ isc_thread_t *threadp)
+{
+ isc_thread_t thread;
+ unsigned int id;
+
+ thread = (isc_thread_t)_beginthreadex(NULL, 0, start, arg, 0, &id);
+ if (thread == NULL) {
+ /* XXX */
+ return (ISC_R_UNEXPECTED);
+ }
+
+ *threadp = thread;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_thread_join(isc_thread_t thread, isc_threadresult_t *rp) {
+ DWORD result;
+ DWORD threadrc;
+
+ result = WaitForSingleObject(thread, INFINITE);
+ if (result != WAIT_OBJECT_0) {
+ /* XXX */
+ return (ISC_R_UNEXPECTED);
+ }
+ if (rp != NULL) {
+ if(!GetExitCodeThread(thread, &threadrc)) {
+ /* XXX */
+ return (ISC_R_UNEXPECTED);
+ }
+ *rp = threadrc;
+ }
+ (void)CloseHandle(thread);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_thread_setconcurrency(unsigned int level) {
+ /*
+ * This is unnecessary on Win32 systems, but is here so that the
+ * call exists
+ */
+}
+
+void *
+isc_thread_key_getspecific(isc_thread_key_t key) {
+ return(TlsGetValue(key));
+}
+
+int
+isc_thread_key_setspecific(isc_thread_key_t key, void *value) {
+ return (TlsSetValue(key, value) ? 0 : GetLastError());
+}
+
+int
+isc_thread_key_create(isc_thread_key_t *key, void (*func)(void *)) {
+ *key = TlsAlloc();
+
+ return ((*key != -1) ? 0 : GetLastError());
+}
+
+int
+isc_thread_key_delete(isc_thread_key_t key) {
+ return (TlsFree(key) ? 0 : GetLastError());
+}
diff --git a/contrib/ntp/libntp/lib/isc/win32/time.c b/contrib/ntp/libntp/lib/isc/win32/time.c
new file mode 100644
index 000000000000..aafd70b124de
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/time.c
@@ -0,0 +1,320 @@
+/*
+ * Copyright (C) 2004, 2006-2009 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: time.c,v 1.52 2009/08/14 07:51:08 marka Exp $ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include <windows.h>
+
+#include <isc/assertions.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+/*
+ * struct FILETIME uses "100-nanoseconds intervals".
+ * NS / S = 1000000000 (10^9).
+ * While it is reasonably obvious that this makes the needed
+ * conversion factor 10^7, it is coded this way for additional clarity.
+ */
+#define NS_PER_S 1000000000
+#define NS_INTERVAL 100
+#define INTERVALS_PER_S (NS_PER_S / NS_INTERVAL)
+#define UINT64_MAX _UI64_MAX
+
+/***
+ *** Absolute Times
+ ***/
+
+static isc_time_t epoch = { { 0, 0 } };
+LIBISC_EXTERNAL_DATA isc_time_t *isc_time_epoch = &epoch;
+
+/***
+ *** Intervals
+ ***/
+
+static isc_interval_t zero_interval = { 0 };
+LIBISC_EXTERNAL_DATA isc_interval_t *isc_interval_zero = &zero_interval;
+
+void
+isc_interval_set(isc_interval_t *i, unsigned int seconds,
+ unsigned int nanoseconds)
+{
+ REQUIRE(i != NULL);
+ REQUIRE(nanoseconds < NS_PER_S);
+
+ /*
+ * This rounds nanoseconds up not down.
+ */
+ i->interval = (LONGLONG)seconds * INTERVALS_PER_S
+ + (nanoseconds + NS_INTERVAL - 1) / NS_INTERVAL;
+}
+
+isc_boolean_t
+isc_interval_iszero(const isc_interval_t *i) {
+ REQUIRE(i != NULL);
+ if (i->interval == 0)
+ return (ISC_TRUE);
+
+ return (ISC_FALSE);
+}
+
+void
+isc_time_set(isc_time_t *t, unsigned int seconds, unsigned int nanoseconds) {
+ SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
+ FILETIME temp;
+ ULARGE_INTEGER i1;
+
+ REQUIRE(t != NULL);
+ REQUIRE(nanoseconds < NS_PER_S);
+
+ SystemTimeToFileTime(&epoch, &temp);
+
+ i1.LowPart = t->absolute.dwLowDateTime;
+ i1.HighPart = t->absolute.dwHighDateTime;
+
+ i1.QuadPart += (unsigned __int64)nanoseconds/100;
+ i1.QuadPart += (unsigned __int64)seconds*10000000;
+
+ t->absolute.dwLowDateTime = i1.LowPart;
+ t->absolute.dwHighDateTime = i1.HighPart;
+}
+
+void
+isc_time_settoepoch(isc_time_t *t) {
+ REQUIRE(t != NULL);
+
+ t->absolute.dwLowDateTime = 0;
+ t->absolute.dwHighDateTime = 0;
+}
+
+isc_boolean_t
+isc_time_isepoch(const isc_time_t *t) {
+ REQUIRE(t != NULL);
+
+ if (t->absolute.dwLowDateTime == 0 &&
+ t->absolute.dwHighDateTime == 0)
+ return (ISC_TRUE);
+
+ return (ISC_FALSE);
+}
+
+isc_result_t
+isc_time_now(isc_time_t *t) {
+ REQUIRE(t != NULL);
+
+ GetSystemTimeAsFileTime(&t->absolute);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_time_nowplusinterval(isc_time_t *t, const isc_interval_t *i) {
+ ULARGE_INTEGER i1;
+
+ REQUIRE(t != NULL);
+ REQUIRE(i != NULL);
+
+ GetSystemTimeAsFileTime(&t->absolute);
+
+ i1.LowPart = t->absolute.dwLowDateTime;
+ i1.HighPart = t->absolute.dwHighDateTime;
+
+ if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
+ return (ISC_R_RANGE);
+
+ i1.QuadPart += i->interval;
+
+ t->absolute.dwLowDateTime = i1.LowPart;
+ t->absolute.dwHighDateTime = i1.HighPart;
+
+ return (ISC_R_SUCCESS);
+}
+
+int
+isc_time_compare(const isc_time_t *t1, const isc_time_t *t2) {
+ REQUIRE(t1 != NULL && t2 != NULL);
+
+ return ((int)CompareFileTime(&t1->absolute, &t2->absolute));
+}
+
+isc_result_t
+isc_time_add(const isc_time_t *t, const isc_interval_t *i, isc_time_t *result)
+{
+ ULARGE_INTEGER i1;
+
+ REQUIRE(t != NULL && i != NULL && result != NULL);
+
+ i1.LowPart = t->absolute.dwLowDateTime;
+ i1.HighPart = t->absolute.dwHighDateTime;
+
+ if (UINT64_MAX - i1.QuadPart < (unsigned __int64)i->interval)
+ return (ISC_R_RANGE);
+
+ i1.QuadPart += i->interval;
+
+ result->absolute.dwLowDateTime = i1.LowPart;
+ result->absolute.dwHighDateTime = i1.HighPart;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_time_subtract(const isc_time_t *t, const isc_interval_t *i,
+ isc_time_t *result) {
+ ULARGE_INTEGER i1;
+
+ REQUIRE(t != NULL && i != NULL && result != NULL);
+
+ i1.LowPart = t->absolute.dwLowDateTime;
+ i1.HighPart = t->absolute.dwHighDateTime;
+
+ if (i1.QuadPart < (unsigned __int64) i->interval)
+ return (ISC_R_RANGE);
+
+ i1.QuadPart -= i->interval;
+
+ result->absolute.dwLowDateTime = i1.LowPart;
+ result->absolute.dwHighDateTime = i1.HighPart;
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_uint64_t
+isc_time_microdiff(const isc_time_t *t1, const isc_time_t *t2) {
+ ULARGE_INTEGER i1, i2;
+ LONGLONG i3;
+
+ REQUIRE(t1 != NULL && t2 != NULL);
+
+ i1.LowPart = t1->absolute.dwLowDateTime;
+ i1.HighPart = t1->absolute.dwHighDateTime;
+ i2.LowPart = t2->absolute.dwLowDateTime;
+ i2.HighPart = t2->absolute.dwHighDateTime;
+
+ if (i1.QuadPart <= i2.QuadPart)
+ return (0);
+
+ /*
+ * Convert to microseconds.
+ */
+ i3 = (i1.QuadPart - i2.QuadPart) / 10;
+
+ return (i3);
+}
+
+isc_uint32_t
+isc_time_seconds(const isc_time_t *t) {
+ SYSTEMTIME epoch = { 1970, 1, 4, 1, 0, 0, 0, 0 };
+ FILETIME temp;
+ ULARGE_INTEGER i1, i2;
+ LONGLONG i3;
+
+ SystemTimeToFileTime(&epoch, &temp);
+
+ i1.LowPart = t->absolute.dwLowDateTime;
+ i1.HighPart = t->absolute.dwHighDateTime;
+ i2.LowPart = temp.dwLowDateTime;
+ i2.HighPart = temp.dwHighDateTime;
+
+ i3 = (i1.QuadPart - i2.QuadPart) / 10000000;
+
+ return ((isc_uint32_t)i3);
+}
+
+isc_uint32_t
+isc_time_nanoseconds(const isc_time_t *t) {
+ ULARGE_INTEGER i;
+
+ i.LowPart = t->absolute.dwLowDateTime;
+ i.HighPart = t->absolute.dwHighDateTime;
+ return ((isc_uint32_t)(i.QuadPart % 10000000) * 100);
+}
+
+void
+isc_time_formattimestamp(const isc_time_t *t, char *buf, unsigned int len) {
+ FILETIME localft;
+ SYSTEMTIME st;
+ char DateBuf[50];
+ char TimeBuf[50];
+
+ static const char badtime[] = "99-Bad-9999 99:99:99.999";
+
+ REQUIRE(len > 0);
+ if (FileTimeToLocalFileTime(&t->absolute, &localft) &&
+ FileTimeToSystemTime(&localft, &st)) {
+ GetDateFormat(LOCALE_USER_DEFAULT, 0, &st, "dd-MMM-yyyy",
+ DateBuf, 50);
+ GetTimeFormat(LOCALE_USER_DEFAULT, TIME_NOTIMEMARKER|
+ TIME_FORCE24HOURFORMAT, &st, NULL, TimeBuf, 50);
+
+ snprintf(buf, len, "%s %s.%03u", DateBuf, TimeBuf,
+ st.wMilliseconds);
+
+ } else
+ snprintf(buf, len, badtime);
+}
+
+void
+isc_time_formathttptimestamp(const isc_time_t *t, char *buf, unsigned int len) {
+ SYSTEMTIME st;
+ char DateBuf[50];
+ char TimeBuf[50];
+
+/* strftime() format: "%a, %d %b %Y %H:%M:%S GMT" */
+
+ REQUIRE(len > 0);
+ if (FileTimeToSystemTime(&t->absolute, &st)) {
+ GetDateFormat(LOCALE_USER_DEFAULT, 0, &st,
+ "ddd',', dd-MMM-yyyy", DateBuf, 50);
+ GetTimeFormat(LOCALE_USER_DEFAULT,
+ TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
+ &st, "hh':'mm':'ss", TimeBuf, 50);
+
+ snprintf(buf, len, "%s %s GMT", DateBuf, TimeBuf);
+ } else {
+ buf[0] = 0;
+ }
+}
+
+void
+isc_time_formatISO8601(const isc_time_t *t, char *buf, unsigned int len) {
+ SYSTEMTIME st;
+ char DateBuf[50];
+ char TimeBuf[50];
+
+/* strtime() format: "%Y-%m-%dT%H:%M:%SZ" */
+
+ REQUIRE(len > 0);
+ if (FileTimeToSystemTime(&t->absolute, &st)) {
+ GetDateFormat(LOCALE_NEUTRAL, 0, &st, "yyyy-MM-dd",
+ DateBuf, 50);
+ GetTimeFormat(LOCALE_NEUTRAL,
+ TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
+ &st, "hh':'mm':'ss", TimeBuf, 50);
+ snprintf(buf, len, "%s%sZ", DateBuf, TimeBuf);
+ } else {
+ buf[0] = 0;
+ }
+}
diff --git a/contrib/ntp/libntp/lib/isc/win32/win32os.c b/contrib/ntp/libntp/lib/isc/win32/win32os.c
new file mode 100644
index 000000000000..56498d0ade10
--- /dev/null
+++ b/contrib/ntp/libntp/lib/isc/win32/win32os.c
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2004, 2007 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2002 Internet Software Consortium.
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+ * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
+ * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+ * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
+ * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* $Id: win32os.c,v 1.5 2007/06/19 23:47:19 tbox Exp $ */
+
+#include <windows.h>
+
+#include <isc/win32os.h>
+
+static BOOL bInit = FALSE;
+static OSVERSIONINFOEX osVer;
+
+static void
+initialize_action(void) {
+ BOOL bSuccess;
+
+ if (bInit)
+ return;
+ /*
+ * NOTE: VC++ 6.0 gets this function declaration wrong
+ * so we compensate by casting the argument
+ */
+ osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+ bSuccess = GetVersionEx((OSVERSIONINFO *) &osVer);
+
+ /*
+ * Versions of NT before NT4.0 SP6 did not return the
+ * extra info that the EX structure provides and returns
+ * a failure so we need to retry with the old structure.
+ */
+ if(!bSuccess) {
+ osVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ bSuccess = GetVersionEx((OSVERSIONINFO *) &osVer);
+ }
+ bInit = TRUE;
+}
+
+unsigned int
+isc_win32os_majorversion(void) {
+ initialize_action();
+ return ((unsigned int)osVer.dwMajorVersion);
+}
+
+unsigned int
+isc_win32os_minorversion(void) {
+ initialize_action();
+ return ((unsigned int)osVer.dwMinorVersion);
+}
+
+unsigned int
+isc_win32os_servicepackmajor(void) {
+ initialize_action();
+ return ((unsigned int)osVer.wServicePackMajor);
+}
+
+unsigned int
+isc_win32os_servicepackminor(void) {
+ initialize_action();
+ return ((unsigned int)osVer.wServicePackMinor);
+}
+
+int
+isc_win32os_versioncheck(unsigned int major, unsigned int minor,
+ unsigned int spmajor, unsigned int spminor) {
+
+ initialize_action();
+
+ if (major < isc_win32os_majorversion())
+ return (1);
+ if (major > isc_win32os_majorversion())
+ return (-1);
+ if (minor < isc_win32os_minorversion())
+ return (1);
+ if (minor > isc_win32os_minorversion())
+ return (-1);
+ if (spmajor < isc_win32os_servicepackmajor())
+ return (1);
+ if (spmajor > isc_win32os_servicepackmajor())
+ return (-1);
+ if (spminor < isc_win32os_servicepackminor())
+ return (1);
+ if (spminor > isc_win32os_servicepackminor())
+ return (-1);
+
+ /* Exact */
+ return (0);
+} \ No newline at end of file