aboutsummaryrefslogtreecommitdiffstats
path: root/lib/isc
diff options
context:
space:
mode:
authorPeter Wemm <peter@FreeBSD.org>2008-07-12 05:00:28 +0000
committerPeter Wemm <peter@FreeBSD.org>2008-07-12 05:00:28 +0000
commita988131922df6e2093bf4391d6b1b021c07d6b3c (patch)
treeceac31a567976fd5866cb5791b059781f6e045de /lib/isc
parent3104e2690b183ef5948f77893efb9ddc3f9edce2 (diff)
downloadsrc-a988131922df6e2093bf4391d6b1b021c07d6b3c.tar.gz
src-a988131922df6e2093bf4391d6b1b021c07d6b3c.zip
Flatten bind9 vendor work area
Notes
Notes: svn path=/vendor/bind9/dist/; revision=180456
Diffstat (limited to 'lib/isc')
-rw-r--r--lib/isc/Makefile.in112
-rw-r--r--lib/isc/alpha/Makefile.in24
-rw-r--r--lib/isc/alpha/include/Makefile.in24
-rw-r--r--lib/isc/alpha/include/isc/Makefile.in36
-rw-r--r--lib/isc/alpha/include/isc/atomic.h170
-rw-r--r--lib/isc/api3
-rw-r--r--lib/isc/arm/include/isc/atomic.h81
-rw-r--r--lib/isc/assertions.c96
-rw-r--r--lib/isc/base64.c250
-rw-r--r--lib/isc/bitstring.c127
-rw-r--r--lib/isc/buffer.c413
-rw-r--r--lib/isc/bufferlist.c64
-rw-r--r--lib/isc/commandline.c222
-rw-r--r--lib/isc/entropy.c1263
-rw-r--r--lib/isc/error.c106
-rw-r--r--lib/isc/event.c88
-rw-r--r--lib/isc/fsaccess.c102
-rw-r--r--lib/isc/hash.c390
-rw-r--r--lib/isc/heap.c256
-rw-r--r--lib/isc/hex.c201
-rw-r--r--lib/isc/hmacmd5.c118
-rw-r--r--lib/isc/hmacsha.c438
-rw-r--r--lib/isc/ia64/Makefile.in24
-rw-r--r--lib/isc/ia64/include/Makefile.in24
-rw-r--r--lib/isc/ia64/include/isc/Makefile.in36
-rw-r--r--lib/isc/ia64/include/isc/atomic.h88
-rw-r--r--lib/isc/include/Makefile.in25
-rw-r--r--lib/isc/include/isc/Makefile.in57
-rw-r--r--lib/isc/include/isc/app.h212
-rw-r--r--lib/isc/include/isc/assertions.h123
-rw-r--r--lib/isc/include/isc/base64.h99
-rw-r--r--lib/isc/include/isc/bitstring.h157
-rw-r--r--lib/isc/include/isc/boolean.h31
-rw-r--r--lib/isc/include/isc/buffer.h811
-rw-r--r--lib/isc/include/isc/bufferlist.h86
-rw-r--r--lib/isc/include/isc/commandline.h50
-rw-r--r--lib/isc/include/isc/entropy.h307
-rw-r--r--lib/isc/include/isc/error.h62
-rw-r--r--lib/isc/include/isc/event.h121
-rw-r--r--lib/isc/include/isc/eventclass.h53
-rw-r--r--lib/isc/include/isc/file.h256
-rw-r--r--lib/isc/include/isc/formatcheck.h40
-rw-r--r--lib/isc/include/isc/fsaccess.h177
-rw-r--r--lib/isc/include/isc/hash.h185
-rw-r--r--lib/isc/include/isc/heap.h170
-rw-r--r--lib/isc/include/isc/hex.h98
-rw-r--r--lib/isc/include/isc/hmacmd5.h63
-rw-r--r--lib/isc/include/isc/hmacsha.h156
-rw-r--r--lib/isc/include/isc/interfaceiter.h133
-rw-r--r--lib/isc/include/isc/ipv6.h148
-rw-r--r--lib/isc/include/isc/lang.h33
-rw-r--r--lib/isc/include/isc/lex.h431
-rw-r--r--lib/isc/include/isc/lfsr.h130
-rw-r--r--lib/isc/include/isc/lib.h41
-rw-r--r--lib/isc/include/isc/list.h184
-rw-r--r--lib/isc/include/isc/log.h913
-rw-r--r--lib/isc/include/isc/magic.h41
-rw-r--r--lib/isc/include/isc/md5.h73
-rw-r--r--lib/isc/include/isc/mem.h543
-rw-r--r--lib/isc/include/isc/msgcat.h131
-rw-r--r--lib/isc/include/isc/msgs.h191
-rw-r--r--lib/isc/include/isc/mutexblock.h71
-rw-r--r--lib/isc/include/isc/netaddr.h175
-rw-r--r--lib/isc/include/isc/netscope.h43
-rw-r--r--lib/isc/include/isc/ondestroy.h116
-rw-r--r--lib/isc/include/isc/os.h38
-rw-r--r--lib/isc/include/isc/parseint.h64
-rw-r--r--lib/isc/include/isc/platform.h.in306
-rw-r--r--lib/isc/include/isc/print.h87
-rw-r--r--lib/isc/include/isc/quota.h119
-rw-r--r--lib/isc/include/isc/random.h62
-rw-r--r--lib/isc/include/isc/ratelimiter.h134
-rw-r--r--lib/isc/include/isc/refcount.h233
-rw-r--r--lib/isc/include/isc/region.h99
-rw-r--r--lib/isc/include/isc/resource.h87
-rw-r--r--lib/isc/include/isc/result.h104
-rw-r--r--lib/isc/include/isc/resultclass.h50
-rw-r--r--lib/isc/include/isc/rwlock.h135
-rw-r--r--lib/isc/include/isc/serial.h75
-rw-r--r--lib/isc/include/isc/sha1.h59
-rw-r--r--lib/isc/include/isc/sha2.h132
-rw-r--r--lib/isc/include/isc/sockaddr.h240
-rw-r--r--lib/isc/include/isc/socket.h752
-rw-r--r--lib/isc/include/isc/stdio.h77
-rw-r--r--lib/isc/include/isc/stdlib.h40
-rw-r--r--lib/isc/include/isc/string.h231
-rw-r--r--lib/isc/include/isc/symtab.h131
-rw-r--r--lib/isc/include/isc/task.h616
-rw-r--r--lib/isc/include/isc/taskpool.h105
-rw-r--r--lib/isc/include/isc/timer.h342
-rw-r--r--lib/isc/include/isc/types.h103
-rw-r--r--lib/isc/include/isc/util.h233
-rw-r--r--lib/isc/include/isc/version.h28
-rw-r--r--lib/isc/inet_aton.c196
-rw-r--r--lib/isc/inet_ntop.c198
-rw-r--r--lib/isc/inet_pton.c214
-rw-r--r--lib/isc/lex.c963
-rw-r--r--lib/isc/lfsr.c161
-rw-r--r--lib/isc/lib.c79
-rw-r--r--lib/isc/log.c1761
-rw-r--r--lib/isc/md5.c251
-rw-r--r--lib/isc/mem.c1955
-rw-r--r--lib/isc/mips/Makefile.in24
-rw-r--r--lib/isc/mips/include/Makefile.in24
-rw-r--r--lib/isc/mips/include/isc/Makefile.in36
-rw-r--r--lib/isc/mips/include/isc/atomic.h98
-rw-r--r--lib/isc/mutexblock.c59
-rw-r--r--lib/isc/netaddr.c436
-rw-r--r--lib/isc/netscope.c76
-rw-r--r--lib/isc/nls/Makefile.in37
-rw-r--r--lib/isc/nls/msgcat.c131
-rw-r--r--lib/isc/noatomic/Makefile.in24
-rw-r--r--lib/isc/noatomic/include/Makefile.in24
-rw-r--r--lib/isc/noatomic/include/isc/Makefile.in36
-rw-r--r--lib/isc/noatomic/include/isc/atomic.h24
-rw-r--r--lib/isc/nothreads/Makefile.in38
-rw-r--r--lib/isc/nothreads/condition.c24
-rw-r--r--lib/isc/nothreads/include/Makefile.in25
-rw-r--r--lib/isc/nothreads/include/isc/Makefile.in37
-rw-r--r--lib/isc/nothreads/include/isc/condition.h59
-rw-r--r--lib/isc/nothreads/include/isc/mutex.h39
-rw-r--r--lib/isc/nothreads/include/isc/once.h32
-rw-r--r--lib/isc/nothreads/include/isc/thread.h35
-rw-r--r--lib/isc/nothreads/mutex.c25
-rw-r--r--lib/isc/nothreads/thread.c28
-rw-r--r--lib/isc/ondestroy.c85
-rw-r--r--lib/isc/parseint.c72
-rw-r--r--lib/isc/powerpc/Makefile.in24
-rw-r--r--lib/isc/powerpc/include/Makefile.in24
-rw-r--r--lib/isc/powerpc/include/isc/Makefile.in36
-rw-r--r--lib/isc/powerpc/include/isc/atomic.h160
-rw-r--r--lib/isc/print.c559
-rw-r--r--lib/isc/pthreads/Makefile.in38
-rw-r--r--lib/isc/pthreads/condition.c74
-rw-r--r--lib/isc/pthreads/include/Makefile.in25
-rw-r--r--lib/isc/pthreads/include/isc/Makefile.in37
-rw-r--r--lib/isc/pthreads/include/isc/condition.h65
-rw-r--r--lib/isc/pthreads/include/isc/mutex.h145
-rw-r--r--lib/isc/pthreads/include/isc/once.h50
-rw-r--r--lib/isc/pthreads/include/isc/thread.h60
-rw-r--r--lib/isc/pthreads/mutex.c270
-rw-r--r--lib/isc/pthreads/thread.c76
-rw-r--r--lib/isc/quota.c101
-rw-r--r--lib/isc/random.c104
-rw-r--r--lib/isc/ratelimiter.c328
-rw-r--r--lib/isc/refcount.c37
-rw-r--r--lib/isc/region.c45
-rw-r--r--lib/isc/result.c212
-rw-r--r--lib/isc/rwlock.c808
-rw-r--r--lib/isc/serial.c59
-rw-r--r--lib/isc/sha1.c315
-rw-r--r--lib/isc/sha2.c1234
-rw-r--r--lib/isc/sockaddr.c503
-rw-r--r--lib/isc/sparc64/Makefile.in24
-rw-r--r--lib/isc/sparc64/include/Makefile.in24
-rw-r--r--lib/isc/sparc64/include/isc/Makefile.in36
-rw-r--r--lib/isc/sparc64/include/isc/atomic.h127
-rw-r--r--lib/isc/string.c270
-rw-r--r--lib/isc/strtoul.c129
-rw-r--r--lib/isc/symtab.c252
-rw-r--r--lib/isc/task.c1298
-rw-r--r--lib/isc/task_p.h31
-rw-r--r--lib/isc/taskpool.c95
-rw-r--r--lib/isc/timer.c930
-rw-r--r--lib/isc/timer_p.h31
-rw-r--r--lib/isc/unix/Makefile.in51
-rw-r--r--lib/isc/unix/app.c683
-rw-r--r--lib/isc/unix/dir.c247
-rw-r--r--lib/isc/unix/entropy.c594
-rw-r--r--lib/isc/unix/errno2result.c123
-rw-r--r--lib/isc/unix/errno2result.h39
-rw-r--r--lib/isc/unix/file.c437
-rw-r--r--lib/isc/unix/fsaccess.c93
-rw-r--r--lib/isc/unix/ifiter_getifaddrs.c185
-rw-r--r--lib/isc/unix/ifiter_ioctl.c1029
-rw-r--r--lib/isc/unix/ifiter_sysctl.c302
-rw-r--r--lib/isc/unix/include/Makefile.in25
-rw-r--r--lib/isc/unix/include/isc/Makefile.in38
-rw-r--r--lib/isc/unix/include/isc/dir.h94
-rw-r--r--lib/isc/unix/include/isc/int.h55
-rw-r--r--lib/isc/unix/include/isc/keyboard.h52
-rw-r--r--lib/isc/unix/include/isc/net.h348
-rw-r--r--lib/isc/unix/include/isc/netdb.h57
-rw-r--r--lib/isc/unix/include/isc/offset.h45
-rw-r--r--lib/isc/unix/include/isc/stat.h52
-rw-r--r--lib/isc/unix/include/isc/stdtime.h60
-rw-r--r--lib/isc/unix/include/isc/strerror.h45
-rw-r--r--lib/isc/unix/include/isc/syslog.h47
-rw-r--r--lib/isc/unix/include/isc/time.h304
-rw-r--r--lib/isc/unix/interfaceiter.c222
-rw-r--r--lib/isc/unix/ipv6.c27
-rw-r--r--lib/isc/unix/keyboard.c126
-rw-r--r--lib/isc/unix/net.c367
-rw-r--r--lib/isc/unix/os.c94
-rw-r--r--lib/isc/unix/resource.c204
-rw-r--r--lib/isc/unix/socket.c3836
-rw-r--r--lib/isc/unix/socket_p.h35
-rw-r--r--lib/isc/unix/stdio.c117
-rw-r--r--lib/isc/unix/stdtime.c86
-rw-r--r--lib/isc/unix/strerror.c74
-rw-r--r--lib/isc/unix/syslog.c84
-rw-r--r--lib/isc/unix/time.c414
-rw-r--r--lib/isc/version.c28
-rw-r--r--lib/isc/x86_32/Makefile.in24
-rw-r--r--lib/isc/x86_32/include/Makefile.in24
-rw-r--r--lib/isc/x86_32/include/isc/Makefile.in36
-rw-r--r--lib/isc/x86_32/include/isc/atomic.h158
-rw-r--r--lib/isc/x86_64/Makefile.in24
-rw-r--r--lib/isc/x86_64/include/Makefile.in24
-rw-r--r--lib/isc/x86_64/include/isc/Makefile.in36
-rw-r--r--lib/isc/x86_64/include/isc/atomic.h103
211 files changed, 43264 insertions, 0 deletions
diff --git a/lib/isc/Makefile.in b/lib/isc/Makefile.in
new file mode 100644
index 000000000000..71e42521da13
--- /dev/null
+++ b/lib/isc/Makefile.in
@@ -0,0 +1,112 @@
+# Copyright (C) 2004-2007 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: Makefile.in,v 1.81.18.8 2007/09/14 23:46:18 tbox Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+@LIBISC_API@
+
+CINCLUDES = -I${srcdir}/unix/include \
+ -I${srcdir}/@ISC_THREAD_DIR@/include \
+ -I${srcdir}/@ISC_ARCH_DIR@/include \
+ -I./include \
+ -I${srcdir}/include
+CDEFINES =
+CWARNINGS =
+
+# Alphabetically
+UNIXOBJS = @ISC_ISCIPV6_O@ \
+ unix/app.@O@ unix/dir.@O@ unix/entropy.@O@ \
+ unix/errno2result.@O@ unix/file.@O@ unix/fsaccess.@O@ \
+ unix/interfaceiter.@O@ unix/keyboard.@O@ unix/net.@O@ \
+ unix/os.@O@ unix/resource.@O@ unix/socket.@O@ unix/stdio.@O@ \
+ unix/stdtime.@O@ unix/strerror.@O@ unix/syslog.@O@ unix/time.@O@
+
+
+NLSOBJS = nls/msgcat.@O@
+
+THREADOBJS = @ISC_THREAD_DIR@/condition.@O@ @ISC_THREAD_DIR@/mutex.@O@ \
+ @ISC_THREAD_DIR@/thread.@O@
+
+WIN32OBJS = win32/condition.@O@ win32/dir.@O@ win32/file.@O@ \
+ win32/fsaccess.@O@ win32/once.@O@ win32/stdtime.@O@ \
+ win32/thread.@O@ win32/time.@O@
+
+# Alphabetically
+OBJS = @ISC_EXTRA_OBJS@ \
+ assertions.@O@ base64.@O@ bitstring.@O@ buffer.@O@ \
+ bufferlist.@O@ commandline.@O@ error.@O@ event.@O@ \
+ hash.@O@ heap.@O@ hex.@O@ hmacmd5.@O@ hmacsha.@O@\
+ lex.@O@ lfsr.@O@ lib.@O@ log.@O@ md5.@O@ \
+ mem.@O@ mutexblock.@O@ netaddr.@O@ netscope.@O@ ondestroy.@O@ \
+ parseint.@O@ quota.@O@ random.@O@ \
+ ratelimiter.@O@ refcount.@O@ region.@O@ result.@O@ rwlock.@O@ \
+ serial.@O@ sha1.@O@ sha2.@O@ sockaddr.@O@ string.@O@ \
+ strtoul.@O@ symtab.@O@ task.@O@ taskpool.@O@ timer.@O@ \
+ version.@O@ ${UNIXOBJS} ${NLSOBJS} ${THREADOBJS}
+
+# Alphabetically
+SRCS = @ISC_EXTRA_SRCS@ \
+ assertions.c base64.c bitstring.c buffer.c \
+ bufferlist.c commandline.c error.c event.c \
+ heap.c hex.c hmacmd5.c hmacsha.c \
+ lex.c lfsr.c lib.c log.c \
+ md5.c mem.c mutexblock.c netaddr.c netscope.c ondestroy.c \
+ parseint.c quota.c random.c \
+ ratelimiter.c refcount.c region.c result.c rwlock.c \
+ serial.c sha1.c sha2.c sockaddr.c string.c strtoul.c symtab.c \
+ task.c taskpool.c timer.c version.c
+
+LIBS = @LIBS@
+
+SUBDIRS = include unix nls @ISC_THREAD_DIR@ @ISC_ARCH_DIR@
+TARGETS = timestamp
+
+@BIND9_MAKE_RULES@
+
+version.@O@: version.c
+ ${LIBTOOL_MODE_COMPILE} ${CC} ${ALL_CFLAGS} \
+ -DVERSION=\"${VERSION}\" \
+ -DLIBINTERFACE=${LIBINTERFACE} \
+ -DLIBREVISION=${LIBREVISION} \
+ -DLIBAGE=${LIBAGE} \
+ -c ${srcdir}/version.c
+
+libisc.@SA@: ${OBJS}
+ ${AR} ${ARFLAGS} $@ ${OBJS}
+ ${RANLIB} $@
+
+libisc.la: ${OBJS}
+ ${LIBTOOL_MODE_LINK} \
+ ${CC} ${ALL_CFLAGS} ${LDFLAGS} -o libisc.la -rpath ${libdir} \
+ -version-info ${LIBINTERFACE}:${LIBREVISION}:${LIBAGE} \
+ ${OBJS} ${LIBS}
+
+timestamp: libisc.@A@
+ touch timestamp
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${libdir}
+
+install:: timestamp installdirs
+ ${LIBTOOL_MODE_INSTALL} ${INSTALL_DATA} libisc.@A@ ${DESTDIR}${libdir}
+
+clean distclean::
+ rm -f libisc.@A@ libisc.la timestamp
diff --git a/lib/isc/alpha/Makefile.in b/lib/isc/alpha/Makefile.in
new file mode 100644
index 000000000000..c8e77e43365c
--- /dev/null
+++ b/lib/isc/alpha/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 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: Makefile.in,v 1.2.2.1 2007/09/14 04:26:38 marka Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = include
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/isc/alpha/include/Makefile.in b/lib/isc/alpha/include/Makefile.in
new file mode 100644
index 000000000000..f4dd2f650c95
--- /dev/null
+++ b/lib/isc/alpha/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 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: Makefile.in,v 1.2.2.1 2007/09/14 04:26:38 marka Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/isc/alpha/include/isc/Makefile.in b/lib/isc/alpha/include/isc/Makefile.in
new file mode 100644
index 000000000000..6760ce61d743
--- /dev/null
+++ b/lib/isc/alpha/include/isc/Makefile.in
@@ -0,0 +1,36 @@
+# Copyright (C) 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: Makefile.in,v 1.2.2.1 2007/09/14 04:26:38 marka Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = atomic.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
+ done
diff --git a/lib/isc/alpha/include/isc/atomic.h b/lib/isc/alpha/include/isc/atomic.h
new file mode 100644
index 000000000000..a4b9b15a02ea
--- /dev/null
+++ b/lib/isc/alpha/include/isc/atomic.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2005 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * 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 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: atomic.h,v 1.2.2.2 2005/06/16 22:01:01 jinmei Exp $ */
+
+/*
+ * This code was written based on FreeBSD's kernel source whose copyright
+ * follows:
+ */
+
+/*-
+ * Copyright (c) 1998 Doug Rabson
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ISC_ATOMIC_H
+#define ISC_ATOMIC_H 1
+
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#ifdef ISC_PLATFORM_USEOSFASM
+#include <c_asm.h>
+
+#pragma intrinsic(asm)
+
+/*
+ * This routine atomically increments the value stored in 'p' by 'val', and
+ * returns the previous value.
+ */
+static inline isc_int32_t
+isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
+ return (asm("1:"
+ "ldl_l %t0, 0(%a0);" /* load old value */
+ "mov %t0, %v0;" /* copy the old value */
+ "addl %t0, %a1, %t0;" /* calculate new value */
+ "stl_c %t0, 0(%a0);" /* attempt to store */
+ "beq %t0, 1b;", /* spin if failed */
+ p, val));
+}
+
+/*
+ * This routine atomically stores the value 'val' in 'p'.
+ */
+static inline void
+isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
+ (void)asm("1:"
+ "ldl_l %t0, 0(%a0);" /* load old value */
+ "mov %a1, %t0;" /* value to store */
+ "stl_c %t0, 0(%a0);" /* attempt to store */
+ "beq %t0, 1b;", /* spin if failed */
+ p, val);
+}
+
+/*
+ * This routine atomically replaces the value in 'p' with 'val', if the
+ * original value is equal to 'cmpval'. The original value is returned in any
+ * case.
+ */
+static inline isc_int32_t
+isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
+
+ return(asm("1:"
+ "ldl_l %t0, 0(%a0);" /* load old value */
+ "mov %t0, %v0;" /* copy the old value */
+ "cmpeq %t0, %a1, %t0;" /* compare */
+ "beq %t0, 2f;" /* exit if not equal */
+ "mov %a2, %t0;" /* value to store */
+ "stl_c %t0, 0(%a0);" /* attempt to store */
+ "beq %t0, 1b;" /* if it failed, spin */
+ "2:",
+ p, cmpval, val));
+}
+#elif defined (ISC_PLATFORM_USEGCCASM)
+static inline isc_int32_t
+isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
+ isc_int32_t temp, prev;
+
+ __asm__ volatile(
+ "1:"
+ "ldl_l %0, %1;" /* load old value */
+ "mov %0, %2;" /* copy the old value */
+ "addl %0, %3, %0;" /* calculate new value */
+ "stl_c %0, %1;" /* attempt to store */
+ "beq %0, 1b;" /* spin if failed */
+ : "=&r"(temp), "+m"(*p), "=r"(prev)
+ : "r"(val)
+ : "memory");
+
+ return (prev);
+}
+
+static inline void
+isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
+ isc_int32_t temp;
+
+ __asm__ volatile(
+ "1:"
+ "ldl_l %0, %1;" /* load old value */
+ "mov %2, %0;" /* value to store */
+ "stl_c %0, %1;" /* attempt to store */
+ "beq %0, 1b;" /* if it failed, spin */
+ : "=&r"(temp), "+m"(*p)
+ : "r"(val)
+ : "memory");
+}
+
+static inline isc_int32_t
+isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
+ isc_int32_t temp, prev;
+
+ __asm__ volatile(
+ "1:"
+ "ldl_l %0, %1;" /* load old value */
+ "mov %0, %2;" /* copy the old value */
+ "cmpeq %0, %3, %0;" /* compare */
+ "beq %0, 2f;" /* exit if not equal */
+ "mov %4, %0;" /* value to store */
+ "stl_c %0, %1;" /* attempt to store */
+ "beq %0, 1b;" /* if it failed, spin */
+ "2:"
+ : "=&r"(temp), "+m"(*p), "=r"(prev)
+ : "r"(cmpval), "r"(val)
+ : "memory");
+
+ return (prev);
+}
+#else
+
+#error "unsupported compiler. disable atomic ops by --disable-atomic"
+
+#endif
+
+#endif /* ISC_ATOMIC_H */
diff --git a/lib/isc/api b/lib/isc/api
new file mode 100644
index 000000000000..ecadc93c94f3
--- /dev/null
+++ b/lib/isc/api
@@ -0,0 +1,3 @@
+LIBINTERFACE = 32
+LIBREVISION = 5
+LIBAGE = 0
diff --git a/lib/isc/arm/include/isc/atomic.h b/lib/isc/arm/include/isc/atomic.h
new file mode 100644
index 000000000000..4c519ee815c5
--- /dev/null
+++ b/lib/isc/arm/include/isc/atomic.h
@@ -0,0 +1,81 @@
+/*-
+ * Copyright (c) 2007 Warner Losh
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef ISC_ATOMIC_H
+#define ISC_ATOMIC_H 1
+
+#include <isc/platform.h>
+#include <isc/types.h>
+#include <machine/atomic.h>
+
+#ifdef __FreeBSD__
+static inline isc_int32_t
+isc_atomic_xadd(isc_int32_t *p, isc_int32_t val)
+{
+ return atomic_fetchadd_int(p, val);
+}
+
+static inline void
+isc_atomic_store(isc_int32_t *p, isc_int32_t val)
+{
+ atomic_store_rel_int(p, val);
+}
+
+static inline isc_int32_t
+isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val)
+{
+ register int done, ras_start;
+
+ __asm __volatile("1:\n"
+ "adr %1, 1b\n"
+ "mov %0, #0xe0000004\n"
+ "str %1, [%0]\n"
+ "mov %0, #0xe0000008\n"
+ "adr %1, 2f\n"
+ "str %1, [%0]\n"
+ "ldr %1, [%2]\n"
+ "cmp %1, %3\n"
+ "streq %4, [%2]\n"
+ "2:\n"
+ "mov %3, #0\n"
+ "mov %0, #0xe0000004\n"
+ "str %3, [%0]\n"
+ "mov %3, #0xffffffff\n"
+ "mov %0, #0xe0000008\n"
+ "str %3, [%0]\n"
+ : "=r" (ras_start), "=r" (done)
+ ,"+r" (p), "+r" (cmpval), "+r" (val) : : "memory");
+ return (done);
+
+}
+#else /* !FreeBSD */
+
+#error "unsupported compiler. disable atomic ops by --disable-atomic"
+
+#endif
+#endif /* ISC_ATOMIC_H */
diff --git a/lib/isc/assertions.c b/lib/isc/assertions.c
new file mode 100644
index 000000000000..b3fcf4a050de
--- /dev/null
+++ b/lib/isc/assertions.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-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 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.17.18.2 2005/04/29 00:16:44 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <isc/assertions.h>
+#include <isc/msgs.h>
+
+/*%
+ * Forward.
+ */
+static void
+default_callback(const char *, int, isc_assertiontype_t, const char *);
+
+/*%
+ * Public.
+ */
+
+LIBISC_EXTERNAL_DATA isc_assertioncallback_t isc_assertion_failed =
+ default_callback;
+
+/*% Set callback. */
+void
+isc_assertion_setcallback(isc_assertioncallback_t cb) {
+ if (cb == NULL)
+ isc_assertion_failed = default_callback;
+ else
+ isc_assertion_failed = 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)
+{
+ fprintf(stderr, "%s:%d: %s(%s) %s.\n",
+ file, line, isc_assertion_typetotext(type), cond,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_GENERAL,
+ ISC_MSG_FAILED, "failed"));
+ fflush(stderr);
+ abort();
+ /* NOTREACHED */
+}
diff --git a/lib/isc/base64.c b/lib/isc/base64.c
new file mode 100644
index 000000000000..faeae92aba0f
--- /dev/null
+++ b/lib/isc/base64.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 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 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: base64.c,v 1.28.18.2 2005/04/29 00:16:44 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <isc/base64.h>
+#include <isc/buffer.h>
+#include <isc/lex.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#define RETERR(x) do { \
+ isc_result_t _r = (x); \
+ if (_r != ISC_R_SUCCESS) \
+ return (_r); \
+ } while (0)
+
+
+/*@{*/
+/*!
+ * These static functions are also present in lib/dns/rdata.c. I'm not
+ * sure where they should go. -- bwelling
+ */
+static isc_result_t
+str_totext(const char *source, isc_buffer_t *target);
+
+static isc_result_t
+mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
+
+static const char base64[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
+/*@}*/
+
+isc_result_t
+isc_base64_totext(isc_region_t *source, int wordlength,
+ const char *wordbreak, isc_buffer_t *target)
+{
+ char buf[5];
+ unsigned int loops = 0;
+
+ if (wordlength < 4)
+ wordlength = 4;
+
+ memset(buf, 0, sizeof(buf));
+ while (source->length > 2) {
+ buf[0] = base64[(source->base[0]>>2)&0x3f];
+ buf[1] = base64[((source->base[0]<<4)&0x30)|
+ ((source->base[1]>>4)&0x0f)];
+ buf[2] = base64[((source->base[1]<<2)&0x3c)|
+ ((source->base[2]>>6)&0x03)];
+ buf[3] = base64[source->base[2]&0x3f];
+ RETERR(str_totext(buf, target));
+ isc_region_consume(source, 3);
+
+ loops++;
+ if (source->length != 0 &&
+ (int)((loops + 1) * 4) >= wordlength)
+ {
+ loops = 0;
+ RETERR(str_totext(wordbreak, target));
+ }
+ }
+ if (source->length == 2) {
+ buf[0] = base64[(source->base[0]>>2)&0x3f];
+ buf[1] = base64[((source->base[0]<<4)&0x30)|
+ ((source->base[1]>>4)&0x0f)];
+ buf[2] = base64[((source->base[1]<<2)&0x3c)];
+ buf[3] = '=';
+ RETERR(str_totext(buf, target));
+ } else if (source->length == 1) {
+ buf[0] = base64[(source->base[0]>>2)&0x3f];
+ buf[1] = base64[((source->base[0]<<4)&0x30)];
+ buf[2] = buf[3] = '=';
+ RETERR(str_totext(buf, target));
+ }
+ return (ISC_R_SUCCESS);
+}
+
+/*%
+ * State of a base64 decoding process in progress.
+ */
+typedef struct {
+ int length; /*%< Desired length of binary data or -1 */
+ isc_buffer_t *target; /*%< Buffer for resulting binary data */
+ int digits; /*%< Number of buffered base64 digits */
+ isc_boolean_t seen_end; /*%< True if "=" end marker seen */
+ int val[4];
+} base64_decode_ctx_t;
+
+static inline void
+base64_decode_init(base64_decode_ctx_t *ctx, int length, isc_buffer_t *target)
+{
+ ctx->digits = 0;
+ ctx->seen_end = ISC_FALSE;
+ ctx->length = length;
+ ctx->target = target;
+}
+
+static inline isc_result_t
+base64_decode_char(base64_decode_ctx_t *ctx, int c) {
+ char *s;
+
+ if (ctx->seen_end)
+ return (ISC_R_BADBASE64);
+ if ((s = strchr(base64, c)) == NULL)
+ return (ISC_R_BADBASE64);
+ ctx->val[ctx->digits++] = s - base64;
+ if (ctx->digits == 4) {
+ int n;
+ unsigned char buf[3];
+ if (ctx->val[0] == 64 || ctx->val[1] == 64)
+ return (ISC_R_BADBASE64);
+ if (ctx->val[2] == 64 && ctx->val[3] != 64)
+ return (ISC_R_BADBASE64);
+ /*
+ * Check that bits that should be zero are.
+ */
+ if (ctx->val[2] == 64 && (ctx->val[1] & 0xf) != 0)
+ return (ISC_R_BADBASE64);
+ /*
+ * We don't need to test for ctx->val[2] != 64 as
+ * the bottom two bits of 64 are zero.
+ */
+ if (ctx->val[3] == 64 && (ctx->val[2] & 0x3) != 0)
+ return (ISC_R_BADBASE64);
+ n = (ctx->val[2] == 64) ? 1 :
+ (ctx->val[3] == 64) ? 2 : 3;
+ if (n != 3) {
+ ctx->seen_end = ISC_TRUE;
+ if (ctx->val[2] == 64)
+ ctx->val[2] = 0;
+ if (ctx->val[3] == 64)
+ ctx->val[3] = 0;
+ }
+ buf[0] = (ctx->val[0]<<2)|(ctx->val[1]>>4);
+ buf[1] = (ctx->val[1]<<4)|(ctx->val[2]>>2);
+ buf[2] = (ctx->val[2]<<6)|(ctx->val[3]);
+ RETERR(mem_tobuffer(ctx->target, buf, n));
+ if (ctx->length >= 0) {
+ if (n > ctx->length)
+ return (ISC_R_BADBASE64);
+ else
+ ctx->length -= n;
+ }
+ ctx->digits = 0;
+ }
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+base64_decode_finish(base64_decode_ctx_t *ctx) {
+ if (ctx->length > 0)
+ return (ISC_R_UNEXPECTEDEND);
+ if (ctx->digits != 0)
+ return (ISC_R_BADBASE64);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
+ base64_decode_ctx_t ctx;
+ isc_textregion_t *tr;
+ isc_token_t token;
+ isc_boolean_t eol;
+
+ base64_decode_init(&ctx, length, target);
+
+ while (!ctx.seen_end && (ctx.length != 0)) {
+ unsigned int i;
+
+ if (length > 0)
+ eol = ISC_FALSE;
+ else
+ eol = ISC_TRUE;
+ RETERR(isc_lex_getmastertoken(lexer, &token,
+ isc_tokentype_string, eol));
+ if (token.type != isc_tokentype_string)
+ break;
+ tr = &token.value.as_textregion;
+ for (i = 0; i < tr->length; i++)
+ RETERR(base64_decode_char(&ctx, tr->base[i]));
+ }
+ if (ctx.length < 0 && !ctx.seen_end)
+ isc_lex_ungettoken(lexer, &token);
+ RETERR(base64_decode_finish(&ctx));
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_base64_decodestring(const char *cstr, isc_buffer_t *target) {
+ base64_decode_ctx_t ctx;
+
+ base64_decode_init(&ctx, -1, target);
+ for (;;) {
+ int c = *cstr++;
+ if (c == '\0')
+ break;
+ if (c == ' ' || c == '\t' || c == '\n' || c== '\r')
+ continue;
+ RETERR(base64_decode_char(&ctx, c));
+ }
+ RETERR(base64_decode_finish(&ctx));
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+str_totext(const char *source, isc_buffer_t *target) {
+ unsigned int l;
+ isc_region_t region;
+
+ isc_buffer_availableregion(target, &region);
+ l = strlen(source);
+
+ if (l > region.length)
+ return (ISC_R_NOSPACE);
+
+ memcpy(region.base, source, l);
+ isc_buffer_add(target, l);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
+ isc_region_t tr;
+
+ isc_buffer_availableregion(target, &tr);
+ if (length > tr.length)
+ return (ISC_R_NOSPACE);
+ memcpy(tr.base, base, length);
+ isc_buffer_add(target, length);
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/isc/bitstring.c b/lib/isc/bitstring.c
new file mode 100644
index 000000000000..105b5aa608bb
--- /dev/null
+++ b/lib/isc/bitstring.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: bitstring.c,v 1.13.18.2 2005/04/29 00:16:44 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include <isc/magic.h>
+#include <isc/bitstring.h>
+#include <isc/util.h>
+
+#define DIV8(x) ((x) >> 3)
+#define MOD8(x) ((x) & 0x00000007U)
+#define OCTETS(n) (((n) + 7) >> 3)
+#define PADDED(n) ((((n) + 7) >> 3) << 3)
+#define BITSET(bs, n) (((bs)->data[DIV8(n)] & \
+ (1 << (7 - MOD8(n)))) != 0)
+#define SETBIT(bs, n) (bs)->data[DIV8(n)] |= (1 << (7 - MOD8(n)))
+#define CLEARBIT(bs, n) (bs)->data[DIV8(n)] &= ~(1 << (7 - MOD8(n)))
+
+#define BITSTRING_MAGIC ISC_MAGIC('B', 'S', 't', 'r')
+#define VALID_BITSTRING(b) ISC_MAGIC_VALID(b, BITSTRING_MAGIC)
+
+void
+isc_bitstring_init(isc_bitstring_t *bitstring, unsigned char *data,
+ unsigned int length, unsigned int size, isc_boolean_t lsb0)
+{
+ /*
+ * Make 'bitstring' refer to the bitstring of 'size' bits starting
+ * at 'data'. 'length' bits of the bitstring are valid. If 'lsb0'
+ * is set then, bit 0 refers to the least significant bit of the
+ * bitstring. Otherwise bit 0 is the most significant bit.
+ */
+
+ REQUIRE(bitstring != NULL);
+ REQUIRE(data != NULL);
+ REQUIRE(length <= size);
+
+ bitstring->magic = BITSTRING_MAGIC;
+ bitstring->data = data;
+ bitstring->length = length;
+ bitstring->size = size;
+ bitstring->lsb0 = lsb0;
+}
+
+void
+isc_bitstring_invalidate(isc_bitstring_t *bitstring) {
+
+ /*
+ * Invalidate 'bitstring'.
+ */
+
+ REQUIRE(VALID_BITSTRING(bitstring));
+
+ bitstring->magic = 0;
+ bitstring->data = NULL;
+ bitstring->length = 0;
+ bitstring->size = 0;
+ bitstring->lsb0 = ISC_FALSE;
+}
+
+void
+isc_bitstring_copy(isc_bitstring_t *source, unsigned int sbitpos,
+ isc_bitstring_t *target, unsigned int tbitpos,
+ unsigned int n)
+{
+ unsigned int tlast;
+
+ /*
+ * Starting at bit 'sbitpos', copy 'n' bits from 'source' to
+ * the 'n' bits of 'target' starting at 'tbitpos'.
+ */
+
+ REQUIRE(VALID_BITSTRING(source));
+ REQUIRE(VALID_BITSTRING(target));
+ REQUIRE(source->lsb0 == target->lsb0);
+ if (source->lsb0) {
+ REQUIRE(sbitpos <= source->length);
+ sbitpos = PADDED(source->size) - sbitpos;
+ REQUIRE(sbitpos >= n);
+ sbitpos -= n;
+ } else
+ REQUIRE(sbitpos + n <= source->length);
+ tlast = tbitpos + n;
+ if (target->lsb0) {
+ REQUIRE(tbitpos <= target->length);
+ tbitpos = PADDED(target->size) - tbitpos;
+ REQUIRE(tbitpos >= n);
+ tbitpos -= n;
+ } else
+ REQUIRE(tlast <= target->size);
+
+ if (tlast > target->length)
+ target->length = tlast;
+
+ /*
+ * This is far from optimal...
+ */
+
+ while (n > 0) {
+ if (BITSET(source, sbitpos))
+ SETBIT(target, tbitpos);
+ else
+ CLEARBIT(target, tbitpos);
+ sbitpos++;
+ tbitpos++;
+ n--;
+ }
+}
diff --git a/lib/isc/buffer.c b/lib/isc/buffer.c
new file mode 100644
index 000000000000..fc07c001840b
--- /dev/null
+++ b/lib/isc/buffer.c
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 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 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.40.18.2 2005/04/29 00:16:44 marka 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_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);
+}
+
+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);
+}
+
+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) {
+ unsigned int 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 += l;
+}
+
+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/lib/isc/bufferlist.c b/lib/isc/bufferlist.c
new file mode 100644
index 000000000000..773d0750c7d1
--- /dev/null
+++ b/lib/isc/bufferlist.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: bufferlist.c,v 1.13.18.2 2005/04/29 00:16:45 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <stddef.h>
+
+#include <isc/buffer.h>
+#include <isc/bufferlist.h>
+#include <isc/util.h>
+
+unsigned int
+isc_bufferlist_usedcount(isc_bufferlist_t *bl) {
+ isc_buffer_t *buffer;
+ unsigned int length;
+
+ REQUIRE(bl != NULL);
+
+ length = 0;
+ buffer = ISC_LIST_HEAD(*bl);
+ while (buffer != NULL) {
+ REQUIRE(ISC_BUFFER_VALID(buffer));
+ length += isc_buffer_usedlength(buffer);
+ buffer = ISC_LIST_NEXT(buffer, link);
+ }
+
+ return (length);
+}
+
+unsigned int
+isc_bufferlist_availablecount(isc_bufferlist_t *bl) {
+ isc_buffer_t *buffer;
+ unsigned int length;
+
+ REQUIRE(bl != NULL);
+
+ length = 0;
+ buffer = ISC_LIST_HEAD(*bl);
+ while (buffer != NULL) {
+ REQUIRE(ISC_BUFFER_VALID(buffer));
+ length += isc_buffer_availablelength(buffer);
+ buffer = ISC_LIST_NEXT(buffer, link);
+ }
+
+ return (length);
+}
diff --git a/lib/isc/commandline.c b/lib/isc/commandline.c
new file mode 100644
index 000000000000..679ed6d60abc
--- /dev/null
+++ b/lib/isc/commandline.c
@@ -0,0 +1,222 @@
+/*
+ * Portions Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Portions 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 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.
+ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * 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: commandline.c,v 1.16.18.2 2005/04/29 00:16:45 marka Exp $ */
+
+/*! \file
+ * This file was adapted from the NetBSD project's source tree, RCS ID:
+ * NetBSD: getopt.c,v 1.15 1999/09/20 04:39:37 lukem Exp
+ *
+ * The primary change has been to rename items to the ISC namespace
+ * and format in the ISC coding style.
+ */
+
+/*
+ * \author Principal Authors: Computer Systems Research Group at UC Berkeley
+ * \author Principal ISC caretaker: DCL
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include <isc/commandline.h>
+#include <isc/msgs.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+/*% Index into parent argv vector. */
+LIBISC_EXTERNAL_DATA int isc_commandline_index = 1;
+/*% Character checked for validity. */
+LIBISC_EXTERNAL_DATA int isc_commandline_option;
+/*% Argument associated with option. */
+LIBISC_EXTERNAL_DATA char *isc_commandline_argument;
+/*% For printing error messages. */
+LIBISC_EXTERNAL_DATA char *isc_commandline_progname;
+/*% Print error messages. */
+LIBISC_EXTERNAL_DATA isc_boolean_t isc_commandline_errprint = ISC_TRUE;
+/*% Reset processing. */
+LIBISC_EXTERNAL_DATA isc_boolean_t isc_commandline_reset = ISC_TRUE;
+
+static char endopt = '\0';
+
+#define BADOPT '?'
+#define BADARG ':'
+#define ENDOPT &endopt
+
+/*!
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+isc_commandline_parse(int argc, char * const *argv, const char *options) {
+ static char *place = ENDOPT;
+ char *option; /* Index into *options of option. */
+
+ REQUIRE(argc >= 0 && argv != NULL && options != NULL);
+
+ /*
+ * Update scanning pointer, either because a reset was requested or
+ * the previous argv was finished.
+ */
+ if (isc_commandline_reset || *place == '\0') {
+ isc_commandline_reset = ISC_FALSE;
+
+ if (isc_commandline_progname == NULL)
+ isc_commandline_progname = argv[0];
+
+ if (isc_commandline_index >= argc ||
+ *(place = argv[isc_commandline_index]) != '-') {
+ /*
+ * Index out of range or points to non-option.
+ */
+ place = ENDOPT;
+ return (-1);
+ }
+
+ if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
+ /*
+ * Found '--' to signal end of options. Advance
+ * index to next argv, the first non-option.
+ */
+ isc_commandline_index++;
+ place = ENDOPT;
+ return (-1);
+ }
+ }
+
+ isc_commandline_option = *place++;
+ option = strchr(options, isc_commandline_option);
+
+ /*
+ * Ensure valid option has been passed as specified by options string.
+ * '-:' is never a valid command line option because it could not
+ * distinguish ':' from the argument specifier in the options string.
+ */
+ if (isc_commandline_option == ':' || option == NULL) {
+ if (*place == '\0')
+ isc_commandline_index++;
+
+ if (isc_commandline_errprint && *options != ':')
+ fprintf(stderr, "%s: %s -- %c\n",
+ isc_commandline_progname,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_COMMANDLINE,
+ ISC_MSG_ILLEGALOPT,
+ "illegal option"),
+ isc_commandline_option);
+
+ return (BADOPT);
+ }
+
+ if (*++option != ':') {
+ /*
+ * Option does not take an argument.
+ */
+ isc_commandline_argument = NULL;
+
+ /*
+ * Skip to next argv if at the end of the current argv.
+ */
+ if (*place == '\0')
+ ++isc_commandline_index;
+
+ } else {
+ /*
+ * Option needs an argument.
+ */
+ if (*place != '\0')
+ /*
+ * Option is in this argv, -D1 style.
+ */
+ isc_commandline_argument = place;
+
+ else if (argc > ++isc_commandline_index)
+ /*
+ * Option is next argv, -D 1 style.
+ */
+ isc_commandline_argument = argv[isc_commandline_index];
+
+ else {
+ /*
+ * Argument needed, but no more argv.
+ */
+ place = ENDOPT;
+
+ /*
+ * Silent failure with "missing argument" return
+ * when ':' starts options string, per historical spec.
+ */
+ if (*options == ':')
+ return (BADARG);
+
+ if (isc_commandline_errprint)
+ fprintf(stderr, "%s: %s -- %c\n",
+ isc_commandline_progname,
+ isc_msgcat_get(isc_msgcat,
+ ISC_MSGSET_COMMANDLINE,
+ ISC_MSG_OPTNEEDARG,
+ "option requires "
+ "an argument"),
+ isc_commandline_option);
+
+ return (BADOPT);
+ }
+
+ place = ENDOPT;
+
+ /*
+ * Point to argv that follows argument.
+ */
+ isc_commandline_index++;
+ }
+
+ return (isc_commandline_option);
+}
diff --git a/lib/isc/entropy.c b/lib/isc/entropy.c
new file mode 100644
index 000000000000..3e87d87e515c
--- /dev/null
+++ b/lib/isc/entropy.c
@@ -0,0 +1,1263 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2003 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 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: entropy.c,v 1.11.18.3 2005/07/12 01:22:28 marka Exp $ */
+
+/*! \file
+ * \brief
+ * This is the system independent part of the entropy module. It is
+ * compiled via inclusion from the relevant OS source file, ie,
+ * \link unix/entropy.c unix/entropy.c \endlink or win32/entropy.c.
+ *
+ * \author Much of this code is modeled after the NetBSD /dev/random implementation,
+ * written by Michael Graff <explorer@netbsd.org>.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+
+#include <isc/buffer.h>
+#include <isc/entropy.h>
+#include <isc/keyboard.h>
+#include <isc/list.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/mutex.h>
+#include <isc/platform.h>
+#include <isc/region.h>
+#include <isc/sha1.h>
+#include <isc/string.h>
+#include <isc/time.h>
+#include <isc/util.h>
+
+
+#define ENTROPY_MAGIC ISC_MAGIC('E', 'n', 't', 'e')
+#define SOURCE_MAGIC ISC_MAGIC('E', 'n', 't', 's')
+
+#define VALID_ENTROPY(e) ISC_MAGIC_VALID(e, ENTROPY_MAGIC)
+#define VALID_SOURCE(s) ISC_MAGIC_VALID(s, SOURCE_MAGIC)
+
+/***
+ *** "constants." Do not change these unless you _really_ know what
+ *** you are doing.
+ ***/
+
+/*%
+ * Size of entropy pool in 32-bit words. This _MUST_ be a power of 2.
+ */
+#define RND_POOLWORDS 128
+/*% Pool in bytes. */
+#define RND_POOLBYTES (RND_POOLWORDS * 4)
+/*% Pool in bits. */
+#define RND_POOLBITS (RND_POOLWORDS * 32)
+
+/*%
+ * Number of bytes returned per hash. This must be true:
+ * threshold * 2 <= digest_size_in_bytes
+ */
+#define RND_ENTROPY_THRESHOLD 10
+#define THRESHOLD_BITS (RND_ENTROPY_THRESHOLD * 8)
+
+/*%
+ * Size of the input event queue in samples.
+ */
+#define RND_EVENTQSIZE 32
+
+/*%
+ * The number of times we'll "reseed" for pseudorandom seeds. This is an
+ * extremely weak pseudorandom seed. If the caller is using lots of
+ * pseudorandom data and they cannot provide a stronger random source,
+ * there is little we can do other than hope they're smart enough to
+ * call _adddata() with something better than we can come up with.
+ */
+#define RND_INITIALIZE 128
+
+/*% Entropy Pool */
+typedef struct {
+ isc_uint32_t cursor; /*%< current add point in the pool */
+ isc_uint32_t entropy; /*%< current entropy estimate in bits */
+ isc_uint32_t pseudo; /*%< bits extracted in pseudorandom */
+ isc_uint32_t rotate; /*%< how many bits to rotate by */
+ isc_uint32_t pool[RND_POOLWORDS]; /*%< random pool data */
+} isc_entropypool_t;
+
+struct isc_entropy {
+ unsigned int magic;
+ isc_mem_t *mctx;
+ isc_mutex_t lock;
+ unsigned int refcnt;
+ isc_uint32_t initialized;
+ isc_uint32_t initcount;
+ isc_entropypool_t pool;
+ unsigned int nsources;
+ isc_entropysource_t *nextsource;
+ ISC_LIST(isc_entropysource_t) sources;
+};
+
+/*% Sample Queue */
+typedef struct {
+ isc_uint32_t last_time; /*%< last time recorded */
+ isc_uint32_t last_delta; /*%< last delta value */
+ isc_uint32_t last_delta2; /*%< last delta2 value */
+ isc_uint32_t nsamples; /*%< number of samples filled in */
+ isc_uint32_t *samples; /*%< the samples */
+ isc_uint32_t *extra; /*%< extra samples added in */
+} sample_queue_t;
+
+typedef struct {
+ sample_queue_t samplequeue;
+} isc_entropysamplesource_t;
+
+typedef struct {
+ isc_boolean_t start_called;
+ isc_entropystart_t startfunc;
+ isc_entropyget_t getfunc;
+ isc_entropystop_t stopfunc;
+ void *arg;
+ sample_queue_t samplequeue;
+} isc_cbsource_t;
+
+typedef struct {
+ FILESOURCE_HANDLE_TYPE handle;
+} isc_entropyfilesource_t;
+
+struct isc_entropysource {
+ unsigned int magic;
+ unsigned int type;
+ isc_entropy_t *ent;
+ isc_uint32_t total; /*%< entropy from this source */
+ ISC_LINK(isc_entropysource_t) link;
+ char name[32];
+ isc_boolean_t bad;
+ isc_boolean_t warn_keyboard;
+ isc_keyboard_t kbd;
+ union {
+ isc_entropysamplesource_t sample;
+ isc_entropyfilesource_t file;
+ isc_cbsource_t callback;
+ isc_entropyusocketsource_t usocket;
+ } sources;
+};
+
+#define ENTROPY_SOURCETYPE_SAMPLE 1 /*%< Type is a sample source */
+#define ENTROPY_SOURCETYPE_FILE 2 /*%< Type is a file source */
+#define ENTROPY_SOURCETYPE_CALLBACK 3 /*%< Type is a callback source */
+#define ENTROPY_SOURCETYPE_USOCKET 4 /*%< Type is a Unix socket source */
+
+/*@{*/
+/*%
+ * The random pool "taps"
+ */
+#define TAP1 99
+#define TAP2 59
+#define TAP3 31
+#define TAP4 9
+#define TAP5 7
+/*@}*/
+
+/*@{*/
+/*%
+ * Declarations for function provided by the system dependent sources that
+ * include this file.
+ */
+static void
+fillpool(isc_entropy_t *, unsigned int, isc_boolean_t);
+
+static int
+wait_for_sources(isc_entropy_t *);
+
+static void
+destroyfilesource(isc_entropyfilesource_t *source);
+
+static void
+destroyusocketsource(isc_entropyusocketsource_t *source);
+
+/*@}*/
+
+static void
+samplequeue_release(isc_entropy_t *ent, sample_queue_t *sq) {
+ REQUIRE(sq->samples != NULL);
+ REQUIRE(sq->extra != NULL);
+
+ isc_mem_put(ent->mctx, sq->samples, RND_EVENTQSIZE * 4);
+ isc_mem_put(ent->mctx, sq->extra, RND_EVENTQSIZE * 4);
+ sq->samples = NULL;
+ sq->extra = NULL;
+}
+
+static isc_result_t
+samplesource_allocate(isc_entropy_t *ent, sample_queue_t *sq) {
+ sq->samples = isc_mem_get(ent->mctx, RND_EVENTQSIZE * 4);
+ if (sq->samples == NULL)
+ return (ISC_R_NOMEMORY);
+
+ sq->extra = isc_mem_get(ent->mctx, RND_EVENTQSIZE * 4);
+ if (sq->extra == NULL) {
+ isc_mem_put(ent->mctx, sq->samples, RND_EVENTQSIZE * 4);
+ sq->samples = NULL;
+ return (ISC_R_NOMEMORY);
+ }
+
+ sq->nsamples = 0;
+
+ return (ISC_R_SUCCESS);
+}
+
+/*%
+ * Add in entropy, even when the value we're adding in could be
+ * very large.
+ */
+static inline void
+add_entropy(isc_entropy_t *ent, isc_uint32_t entropy) {
+ /* clamp input. Yes, this must be done. */
+ entropy = ISC_MIN(entropy, RND_POOLBITS);
+ /* Add in the entropy we already have. */
+ entropy += ent->pool.entropy;
+ /* Clamp. */
+ ent->pool.entropy = ISC_MIN(entropy, RND_POOLBITS);
+}
+
+/*%
+ * Decrement the amount of entropy the pool has.
+ */
+static inline void
+subtract_entropy(isc_entropy_t *ent, isc_uint32_t entropy) {
+ entropy = ISC_MIN(entropy, ent->pool.entropy);
+ ent->pool.entropy -= entropy;
+}
+
+/*!
+ * Add in entropy, even when the value we're adding in could be
+ * very large.
+ */
+static inline void
+add_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) {
+ /* clamp input. Yes, this must be done. */
+ pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8);
+ /* Add in the pseudo we already have. */
+ pseudo += ent->pool.pseudo;
+ /* Clamp. */
+ ent->pool.pseudo = ISC_MIN(pseudo, RND_POOLBITS * 8);
+}
+
+/*!
+ * Decrement the amount of pseudo the pool has.
+ */
+static inline void
+subtract_pseudo(isc_entropy_t *ent, isc_uint32_t pseudo) {
+ pseudo = ISC_MIN(pseudo, ent->pool.pseudo);
+ ent->pool.pseudo -= pseudo;
+}
+
+/*!
+ * Add one word to the pool, rotating the input as needed.
+ */
+static inline void
+entropypool_add_word(isc_entropypool_t *rp, isc_uint32_t val) {
+ /*
+ * Steal some values out of the pool, and xor them into the
+ * word we were given.
+ *
+ * Mix the new value into the pool using xor. This will
+ * prevent the actual values from being known to the caller
+ * since the previous values are assumed to be unknown as well.
+ */
+ val ^= rp->pool[(rp->cursor + TAP1) & (RND_POOLWORDS - 1)];
+ val ^= rp->pool[(rp->cursor + TAP2) & (RND_POOLWORDS - 1)];
+ val ^= rp->pool[(rp->cursor + TAP3) & (RND_POOLWORDS - 1)];
+ val ^= rp->pool[(rp->cursor + TAP4) & (RND_POOLWORDS - 1)];
+ val ^= rp->pool[(rp->cursor + TAP5) & (RND_POOLWORDS - 1)];
+ rp->pool[rp->cursor++] ^=
+ ((val << rp->rotate) | (val >> (32 - rp->rotate)));
+
+ /*
+ * If we have looped around the pool, increment the rotate
+ * variable so the next value will get xored in rotated to
+ * a different position.
+ * Increment by a value that is relativly prime to the word size
+ * to try to spread the bits throughout the pool quickly when the
+ * pool is empty.
+ */
+ if (rp->cursor == RND_POOLWORDS) {
+ rp->cursor = 0;
+ rp->rotate = (rp->rotate + 7) & 31;
+ }
+}
+
+/*!
+ * Add a buffer's worth of data to the pool.
+ *
+ * Requires that the lock is held on the entropy pool.
+ */
+static void
+entropypool_adddata(isc_entropy_t *ent, void *p, unsigned int len,
+ isc_uint32_t entropy)
+{
+ isc_uint32_t val;
+ unsigned long addr;
+ isc_uint8_t *buf;
+
+ addr = (unsigned long)p;
+ buf = p;
+
+ if ((addr & 0x03U) != 0U) {
+ val = 0;
+ switch (len) {
+ case 3:
+ val = *buf++;
+ len--;
+ case 2:
+ val = val << 8 | *buf++;
+ len--;
+ case 1:
+ val = val << 8 | *buf++;
+ len--;
+ }
+
+ entropypool_add_word(&ent->pool, val);
+ }
+
+ for (; len > 3; len -= 4) {
+ val = *((isc_uint32_t *)buf);
+
+ entropypool_add_word(&ent->pool, val);
+ buf += 4;
+ }
+
+ if (len != 0) {
+ val = 0;
+ switch (len) {
+ case 3:
+ val = *buf++;
+ case 2:
+ val = val << 8 | *buf++;
+ case 1:
+ val = val << 8 | *buf++;
+ }
+
+ entropypool_add_word(&ent->pool, val);
+ }
+
+ add_entropy(ent, entropy);
+ subtract_pseudo(ent, entropy);
+}
+
+static inline void
+reseed(isc_entropy_t *ent) {
+ isc_time_t t;
+ pid_t pid;
+
+ if (ent->initcount == 0) {
+ pid = getpid();
+ entropypool_adddata(ent, &pid, sizeof(pid), 0);
+ pid = getppid();
+ entropypool_adddata(ent, &pid, sizeof(pid), 0);
+ }
+
+ /*!
+ * After we've reseeded 100 times, only add new timing info every
+ * 50 requests. This will keep us from using lots and lots of
+ * CPU just to return bad pseudorandom data anyway.
+ */
+ if (ent->initcount > 100)
+ if ((ent->initcount % 50) != 0)
+ return;
+
+ TIME_NOW(&t);
+ entropypool_adddata(ent, &t, sizeof(t), 0);
+ ent->initcount++;
+}
+
+static inline unsigned int
+estimate_entropy(sample_queue_t *sq, isc_uint32_t t) {
+ isc_int32_t delta;
+ isc_int32_t delta2;
+ isc_int32_t delta3;
+
+ /*!
+ * If the time counter has overflowed, calculate the real difference.
+ * If it has not, it is simpler.
+ */
+ if (t < sq->last_time)
+ delta = UINT_MAX - sq->last_time + t;
+ else
+ delta = sq->last_time - t;
+
+ if (delta < 0)
+ delta = -delta;
+
+ /*
+ * Calculate the second and third order differentials
+ */
+ delta2 = sq->last_delta - delta;
+ if (delta2 < 0)
+ delta2 = -delta2;
+
+ delta3 = sq->last_delta2 - delta2;
+ if (delta3 < 0)
+ delta3 = -delta3;
+
+ sq->last_time = t;
+ sq->last_delta = delta;
+ sq->last_delta2 = delta2;
+
+ /*
+ * If any delta is 0, we got no entropy. If all are non-zero, we
+ * might have something.
+ */
+ if (delta == 0 || delta2 == 0 || delta3 == 0)
+ return 0;
+
+ /*
+ * We could find the smallest delta and claim we got log2(delta)
+ * bits, but for now return that we found 1 bit.
+ */
+ return 1;
+}
+
+static unsigned int
+crunchsamples(isc_entropy_t *ent, sample_queue_t *sq) {
+ unsigned int ns;
+ unsigned int added;
+
+ if (sq->nsamples < 6)
+ return (0);
+
+ added = 0;
+ sq->last_time = sq->samples[0];
+ sq->last_delta = 0;
+ sq->last_delta2 = 0;
+
+ /*
+ * Prime the values by adding in the first 4 samples in. This
+ * should completely initialize the delta calculations.
+ */
+ for (ns = 0; ns < 4; ns++)
+ (void)estimate_entropy(sq, sq->samples[ns]);
+
+ for (ns = 4; ns < sq->nsamples; ns++)
+ added += estimate_entropy(sq, sq->samples[ns]);
+
+ entropypool_adddata(ent, sq->samples, sq->nsamples * 4, added);
+ entropypool_adddata(ent, sq->extra, sq->nsamples * 4, 0);
+
+ /*
+ * Move the last 4 samples into the first 4 positions, and start
+ * adding new samples from that point.
+ */
+ for (ns = 0; ns < 4; ns++) {
+ sq->samples[ns] = sq->samples[sq->nsamples - 4 + ns];
+ sq->extra[ns] = sq->extra[sq->nsamples - 4 + ns];
+ }
+
+ sq->nsamples = 4;
+
+ return (added);
+}
+
+static unsigned int
+get_from_callback(isc_entropysource_t *source, unsigned int desired,
+ isc_boolean_t blocking)
+{
+ isc_entropy_t *ent = source->ent;
+ isc_cbsource_t *cbs = &source->sources.callback;
+ unsigned int added;
+ unsigned int got;
+ isc_result_t result;
+
+ if (desired == 0)
+ return (0);
+
+ if (source->bad)
+ return (0);
+
+ if (!cbs->start_called && cbs->startfunc != NULL) {
+ result = cbs->startfunc(source, cbs->arg, blocking);
+ if (result != ISC_R_SUCCESS)
+ return (0);
+ cbs->start_called = ISC_TRUE;
+ }
+
+ added = 0;
+ result = ISC_R_SUCCESS;
+ while (desired > 0 && result == ISC_R_SUCCESS) {
+ result = cbs->getfunc(source, cbs->arg, blocking);
+ if (result == ISC_R_QUEUEFULL) {
+ got = crunchsamples(ent, &cbs->samplequeue);
+ added += got;
+ desired -= ISC_MIN(got, desired);
+ result = ISC_R_SUCCESS;
+ } else if (result != ISC_R_SUCCESS &&
+ result != ISC_R_NOTBLOCKING)
+ source->bad = ISC_TRUE;
+
+ }
+
+ return (added);
+}
+
+/*
+ * Extract some number of bytes from the random pool, decreasing the
+ * estimate of randomness as each byte is extracted.
+ *
+ * Do this by stiring the pool and returning a part of hash as randomness.
+ * Note that no secrets are given away here since parts of the hash are
+ * xored together before returned.
+ *
+ * Honor the request from the caller to only return good data, any data,
+ * etc.
+ */
+isc_result_t
+isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
+ unsigned int *returned, unsigned int flags)
+{
+ unsigned int i;
+ isc_sha1_t hash;
+ unsigned char digest[ISC_SHA1_DIGESTLENGTH];
+ isc_uint32_t remain, deltae, count, total;
+ isc_uint8_t *buf;
+ isc_boolean_t goodonly, partial, blocking;
+
+ REQUIRE(VALID_ENTROPY(ent));
+ REQUIRE(data != NULL);
+ REQUIRE(length > 0);
+
+ goodonly = ISC_TF((flags & ISC_ENTROPY_GOODONLY) != 0);
+ partial = ISC_TF((flags & ISC_ENTROPY_PARTIAL) != 0);
+ blocking = ISC_TF((flags & ISC_ENTROPY_BLOCKING) != 0);
+
+ REQUIRE(!partial || returned != NULL);
+
+ LOCK(&ent->lock);
+
+ remain = length;
+ buf = data;
+ total = 0;
+ while (remain != 0) {
+ count = ISC_MIN(remain, RND_ENTROPY_THRESHOLD);
+
+ /*
+ * If we are extracting good data only, make certain we
+ * have enough data in our pool for this pass. If we don't,
+ * get some, and fail if we can't, and partial returns
+ * are not ok.
+ */
+ if (goodonly) {
+ unsigned int fillcount;
+
+ fillcount = ISC_MAX(remain * 8, count * 8);
+
+ /*
+ * If, however, we have at least THRESHOLD_BITS
+ * of entropy in the pool, don't block here. It is
+ * better to drain the pool once in a while and
+ * then refill it than it is to constantly keep the
+ * pool full.
+ */
+ if (ent->pool.entropy >= THRESHOLD_BITS)
+ fillpool(ent, fillcount, ISC_FALSE);
+ else
+ fillpool(ent, fillcount, blocking);
+
+ /*
+ * Verify that we got enough entropy to do one
+ * extraction. If we didn't, bail.
+ */
+ if (ent->pool.entropy < THRESHOLD_BITS) {
+ if (!partial)
+ goto zeroize;
+ else
+ goto partial_output;
+ }
+ } else {
+ /*
+ * If we've extracted half our pool size in bits
+ * since the last refresh, try to refresh here.
+ */
+ if (ent->initialized < THRESHOLD_BITS)
+ fillpool(ent, THRESHOLD_BITS, blocking);
+ else
+ fillpool(ent, 0, ISC_FALSE);
+
+ /*
+ * If we've not initialized with enough good random
+ * data, seed with our crappy code.
+ */
+ if (ent->initialized < THRESHOLD_BITS)
+ reseed(ent);
+ }
+
+ isc_sha1_init(&hash);
+ isc_sha1_update(&hash, (void *)(ent->pool.pool),
+ RND_POOLBYTES);
+ isc_sha1_final(&hash, digest);
+
+ /*
+ * Stir the extracted data (all of it) back into the pool.
+ */
+ entropypool_adddata(ent, digest, ISC_SHA1_DIGESTLENGTH, 0);
+
+ for (i = 0; i < count; i++)
+ buf[i] = digest[i] ^ digest[i + RND_ENTROPY_THRESHOLD];
+
+ buf += count;
+ remain -= count;
+
+ deltae = count * 8;
+ deltae = ISC_MIN(deltae, ent->pool.entropy);
+ total += deltae;
+ subtract_entropy(ent, deltae);
+ add_pseudo(ent, count * 8);
+ }
+
+ partial_output:
+ memset(digest, 0, sizeof(digest));
+
+ if (returned != NULL)
+ *returned = (length - remain);
+
+ UNLOCK(&ent->lock);
+
+ return (ISC_R_SUCCESS);
+
+ zeroize:
+ /* put the entropy we almost extracted back */
+ add_entropy(ent, total);
+ memset(data, 0, length);
+ memset(digest, 0, sizeof(digest));
+ if (returned != NULL)
+ *returned = 0;
+
+ UNLOCK(&ent->lock);
+
+ return (ISC_R_NOENTROPY);
+}
+
+static void
+isc_entropypool_init(isc_entropypool_t *pool) {
+ pool->cursor = RND_POOLWORDS - 1;
+ pool->entropy = 0;
+ pool->pseudo = 0;
+ pool->rotate = 0;
+ memset(pool->pool, 0, RND_POOLBYTES);
+}
+
+static void
+isc_entropypool_invalidate(isc_entropypool_t *pool) {
+ pool->cursor = 0;
+ pool->entropy = 0;
+ pool->pseudo = 0;
+ pool->rotate = 0;
+ memset(pool->pool, 0, RND_POOLBYTES);
+}
+
+isc_result_t
+isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp) {
+ isc_result_t result;
+ isc_entropy_t *ent;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(entp != NULL && *entp == NULL);
+
+ ent = isc_mem_get(mctx, sizeof(isc_entropy_t));
+ if (ent == NULL)
+ return (ISC_R_NOMEMORY);
+
+ /*
+ * We need a lock.
+ */
+ result = isc_mutex_init(&ent->lock);
+ if (result != ISC_R_SUCCESS)
+ goto errout;
+
+ /*
+ * From here down, no failures will/can occur.
+ */
+ ISC_LIST_INIT(ent->sources);
+ ent->nextsource = NULL;
+ ent->nsources = 0;
+ ent->mctx = NULL;
+ isc_mem_attach(mctx, &ent->mctx);
+ ent->refcnt = 1;
+ ent->initialized = 0;
+ ent->initcount = 0;
+ ent->magic = ENTROPY_MAGIC;
+
+ isc_entropypool_init(&ent->pool);
+
+ *entp = ent;
+ return (ISC_R_SUCCESS);
+
+ errout:
+ isc_mem_put(mctx, ent, sizeof(isc_entropy_t));
+
+ return (result);
+}
+
+/*!
+ * Requires "ent" be locked.
+ */
+static void
+destroysource(isc_entropysource_t **sourcep) {
+ isc_entropysource_t *source;
+ isc_entropy_t *ent;
+ isc_cbsource_t *cbs;
+
+ source = *sourcep;
+ *sourcep = NULL;
+ ent = source->ent;
+
+ ISC_LIST_UNLINK(ent->sources, source, link);
+ ent->nextsource = NULL;
+ REQUIRE(ent->nsources > 0);
+ ent->nsources--;
+
+ switch (source->type) {
+ case ENTROPY_SOURCETYPE_FILE:
+ if (! source->bad)
+ destroyfilesource(&source->sources.file);
+ break;
+ case ENTROPY_SOURCETYPE_USOCKET:
+ if (! source->bad)
+ destroyusocketsource(&source->sources.usocket);
+ break;
+ case ENTROPY_SOURCETYPE_SAMPLE:
+ samplequeue_release(ent, &source->sources.sample.samplequeue);
+ break;
+ case ENTROPY_SOURCETYPE_CALLBACK:
+ cbs = &source->sources.callback;
+ if (cbs->start_called && cbs->stopfunc != NULL) {
+ cbs->stopfunc(source, cbs->arg);
+ cbs->start_called = ISC_FALSE;
+ }
+ samplequeue_release(ent, &cbs->samplequeue);
+ break;
+ }
+
+ memset(source, 0, sizeof(isc_entropysource_t));
+
+ isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t));
+}
+
+static inline isc_boolean_t
+destroy_check(isc_entropy_t *ent) {
+ isc_entropysource_t *source;
+
+ if (ent->refcnt > 0)
+ return (ISC_FALSE);
+
+ source = ISC_LIST_HEAD(ent->sources);
+ while (source != NULL) {
+ switch (source->type) {
+ case ENTROPY_SOURCETYPE_FILE:
+ case ENTROPY_SOURCETYPE_USOCKET:
+ break;
+ default:
+ return (ISC_FALSE);
+ }
+ source = ISC_LIST_NEXT(source, link);
+ }
+
+ return (ISC_TRUE);
+}
+
+static void
+destroy(isc_entropy_t **entp) {
+ isc_entropy_t *ent;
+ isc_entropysource_t *source;
+ isc_mem_t *mctx;
+
+ REQUIRE(entp != NULL && *entp != NULL);
+ ent = *entp;
+ *entp = NULL;
+
+ LOCK(&ent->lock);
+
+ REQUIRE(ent->refcnt == 0);
+
+ /*
+ * Here, detach non-sample sources.
+ */
+ source = ISC_LIST_HEAD(ent->sources);
+ while (source != NULL) {
+ switch(source->type) {
+ case ENTROPY_SOURCETYPE_FILE:
+ case ENTROPY_SOURCETYPE_USOCKET:
+ destroysource(&source);
+ break;
+ }
+ source = ISC_LIST_HEAD(ent->sources);
+ }
+
+ /*
+ * If there are other types of sources, we've found a bug.
+ */
+ REQUIRE(ISC_LIST_EMPTY(ent->sources));
+
+ mctx = ent->mctx;
+
+ isc_entropypool_invalidate(&ent->pool);
+
+ UNLOCK(&ent->lock);
+
+ DESTROYLOCK(&ent->lock);
+
+ memset(ent, 0, sizeof(isc_entropy_t));
+ isc_mem_put(mctx, ent, sizeof(isc_entropy_t));
+ isc_mem_detach(&mctx);
+}
+
+void
+isc_entropy_destroysource(isc_entropysource_t **sourcep) {
+ isc_entropysource_t *source;
+ isc_entropy_t *ent;
+ isc_boolean_t killit;
+
+ REQUIRE(sourcep != NULL);
+ REQUIRE(VALID_SOURCE(*sourcep));
+
+ source = *sourcep;
+ *sourcep = NULL;
+
+ ent = source->ent;
+ REQUIRE(VALID_ENTROPY(ent));
+
+ LOCK(&ent->lock);
+
+ destroysource(&source);
+
+ killit = destroy_check(ent);
+
+ UNLOCK(&ent->lock);
+
+ if (killit)
+ destroy(&ent);
+}
+
+isc_result_t
+isc_entropy_createcallbacksource(isc_entropy_t *ent,
+ isc_entropystart_t start,
+ isc_entropyget_t get,
+ isc_entropystop_t stop,
+ void *arg,
+ isc_entropysource_t **sourcep)
+{
+ isc_result_t result;
+ isc_entropysource_t *source;
+ isc_cbsource_t *cbs;
+
+ REQUIRE(VALID_ENTROPY(ent));
+ REQUIRE(get != NULL);
+ REQUIRE(sourcep != NULL && *sourcep == NULL);
+
+ LOCK(&ent->lock);
+
+ source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
+ if (source == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto errout;
+ }
+ source->bad = ISC_FALSE;
+
+ cbs = &source->sources.callback;
+
+ result = samplesource_allocate(ent, &cbs->samplequeue);
+ if (result != ISC_R_SUCCESS)
+ goto errout;
+
+ cbs->start_called = ISC_FALSE;
+ cbs->startfunc = start;
+ cbs->getfunc = get;
+ cbs->stopfunc = stop;
+ cbs->arg = arg;
+
+ /*
+ * From here down, no failures can occur.
+ */
+ source->magic = SOURCE_MAGIC;
+ source->type = ENTROPY_SOURCETYPE_CALLBACK;
+ source->ent = ent;
+ source->total = 0;
+ memset(source->name, 0, sizeof(source->name));
+ ISC_LINK_INIT(source, link);
+
+ /*
+ * Hook it into the entropy system.
+ */
+ ISC_LIST_APPEND(ent->sources, source, link);
+ ent->nsources++;
+
+ *sourcep = source;
+
+ UNLOCK(&ent->lock);
+ return (ISC_R_SUCCESS);
+
+ errout:
+ if (source != NULL)
+ isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t));
+
+ UNLOCK(&ent->lock);
+
+ return (result);
+}
+
+void
+isc_entropy_stopcallbacksources(isc_entropy_t *ent) {
+ isc_entropysource_t *source;
+ isc_cbsource_t *cbs;
+
+ REQUIRE(VALID_ENTROPY(ent));
+
+ LOCK(&ent->lock);
+
+ source = ISC_LIST_HEAD(ent->sources);
+ while (source != NULL) {
+ if (source->type == ENTROPY_SOURCETYPE_CALLBACK) {
+ cbs = &source->sources.callback;
+ if (cbs->start_called && cbs->stopfunc != NULL) {
+ cbs->stopfunc(source, cbs->arg);
+ cbs->start_called = ISC_FALSE;
+ }
+ }
+
+ source = ISC_LIST_NEXT(source, link);
+ }
+
+ UNLOCK(&ent->lock);
+}
+
+isc_result_t
+isc_entropy_createsamplesource(isc_entropy_t *ent,
+ isc_entropysource_t **sourcep)
+{
+ isc_result_t result;
+ isc_entropysource_t *source;
+ sample_queue_t *sq;
+
+ REQUIRE(VALID_ENTROPY(ent));
+ REQUIRE(sourcep != NULL && *sourcep == NULL);
+
+ LOCK(&ent->lock);
+
+ source = isc_mem_get(ent->mctx, sizeof(isc_entropysource_t));
+ if (source == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto errout;
+ }
+
+ sq = &source->sources.sample.samplequeue;
+ result = samplesource_allocate(ent, sq);
+ if (result != ISC_R_SUCCESS)
+ goto errout;
+
+ /*
+ * From here down, no failures can occur.
+ */
+ source->magic = SOURCE_MAGIC;
+ source->type = ENTROPY_SOURCETYPE_SAMPLE;
+ source->ent = ent;
+ source->total = 0;
+ memset(source->name, 0, sizeof(source->name));
+ ISC_LINK_INIT(source, link);
+
+ /*
+ * Hook it into the entropy system.
+ */
+ ISC_LIST_APPEND(ent->sources, source, link);
+ ent->nsources++;
+
+ *sourcep = source;
+
+ UNLOCK(&ent->lock);
+ return (ISC_R_SUCCESS);
+
+ errout:
+ if (source != NULL)
+ isc_mem_put(ent->mctx, source, sizeof(isc_entropysource_t));
+
+ UNLOCK(&ent->lock);
+
+ return (result);
+}
+
+/*!
+ * Add a sample, and return ISC_R_SUCCESS if the queue has become full,
+ * ISC_R_NOENTROPY if it has space remaining, and ISC_R_NOMORE if the
+ * queue was full when this function was called.
+ */
+static isc_result_t
+addsample(sample_queue_t *sq, isc_uint32_t sample, isc_uint32_t extra) {
+ if (sq->nsamples >= RND_EVENTQSIZE)
+ return (ISC_R_NOMORE);
+
+ sq->samples[sq->nsamples] = sample;
+ sq->extra[sq->nsamples] = extra;
+ sq->nsamples++;
+
+ if (sq->nsamples >= RND_EVENTQSIZE)
+ return (ISC_R_QUEUEFULL);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample,
+ isc_uint32_t extra)
+{
+ isc_entropy_t *ent;
+ sample_queue_t *sq;
+ unsigned int entropy;
+ isc_result_t result;
+
+ REQUIRE(VALID_SOURCE(source));
+
+ ent = source->ent;
+
+ LOCK(&ent->lock);
+
+ sq = &source->sources.sample.samplequeue;
+ result = addsample(sq, sample, extra);
+ if (result == ISC_R_QUEUEFULL) {
+ entropy = crunchsamples(ent, sq);
+ add_entropy(ent, entropy);
+ }
+
+ UNLOCK(&ent->lock);
+
+ return (result);
+}
+
+isc_result_t
+isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample,
+ isc_uint32_t extra)
+{
+ sample_queue_t *sq;
+ isc_result_t result;
+
+ REQUIRE(VALID_SOURCE(source));
+ REQUIRE(source->type == ENTROPY_SOURCETYPE_CALLBACK);
+
+ sq = &source->sources.callback.samplequeue;
+ result = addsample(sq, sample, extra);
+
+ return (result);
+}
+
+void
+isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length,
+ isc_uint32_t entropy)
+{
+ REQUIRE(VALID_ENTROPY(ent));
+
+ LOCK(&ent->lock);
+
+ entropypool_adddata(ent, data, length, entropy);
+
+ if (ent->initialized < THRESHOLD_BITS)
+ ent->initialized = THRESHOLD_BITS;
+
+ UNLOCK(&ent->lock);
+}
+
+static void
+dumpstats(isc_entropy_t *ent, FILE *out) {
+ fprintf(out,
+ isc_msgcat_get(isc_msgcat, ISC_MSGSET_ENTROPY,
+ ISC_MSG_ENTROPYSTATS,
+ "Entropy pool %p: refcnt %u cursor %u,"
+ " rotate %u entropy %u pseudo %u nsources %u"
+ " nextsource %p initialized %u initcount %u\n"),
+ ent, ent->refcnt,
+ ent->pool.cursor, ent->pool.rotate,
+ ent->pool.entropy, ent->pool.pseudo,
+ ent->nsources, ent->nextsource, ent->initialized,
+ ent->initcount);
+}
+
+/*
+ * This function ignores locking. Use at your own risk.
+ */
+void
+isc_entropy_stats(isc_entropy_t *ent, FILE *out) {
+ REQUIRE(VALID_ENTROPY(ent));
+
+ LOCK(&ent->lock);
+ dumpstats(ent, out);
+ UNLOCK(&ent->lock);
+}
+
+void
+isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp) {
+ REQUIRE(VALID_ENTROPY(ent));
+ REQUIRE(entp != NULL && *entp == NULL);
+
+ LOCK(&ent->lock);
+
+ ent->refcnt++;
+ *entp = ent;
+
+ UNLOCK(&ent->lock);
+}
+
+void
+isc_entropy_detach(isc_entropy_t **entp) {
+ isc_entropy_t *ent;
+ isc_boolean_t killit;
+
+ REQUIRE(entp != NULL && VALID_ENTROPY(*entp));
+ ent = *entp;
+ *entp = NULL;
+
+ LOCK(&ent->lock);
+
+ REQUIRE(ent->refcnt > 0);
+ ent->refcnt--;
+
+ killit = destroy_check(ent);
+
+ UNLOCK(&ent->lock);
+
+ if (killit)
+ destroy(&ent);
+}
+
+static isc_result_t
+kbdstart(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) {
+ /*
+ * The intent of "first" is to provide a warning message only once
+ * during the run of a program that might try to gather keyboard
+ * entropy multiple times.
+ */
+ static isc_boolean_t first = ISC_TRUE;
+
+ UNUSED(arg);
+
+ if (! blocking)
+ return (ISC_R_NOENTROPY);
+
+ if (first) {
+ if (source->warn_keyboard)
+ fprintf(stderr, "You must use the keyboard to create "
+ "entropy, since your system is lacking\n"
+ "/dev/random (or equivalent)\n\n");
+ first = ISC_FALSE;
+ }
+ fprintf(stderr, "start typing:\n");
+
+ return (isc_keyboard_open(&source->kbd));
+}
+
+static void
+kbdstop(isc_entropysource_t *source, void *arg) {
+
+ UNUSED(arg);
+
+ if (! isc_keyboard_canceled(&source->kbd))
+ fprintf(stderr, "stop typing.\r\n");
+
+ (void)isc_keyboard_close(&source->kbd, 3);
+}
+
+static isc_result_t
+kbdget(isc_entropysource_t *source, void *arg, isc_boolean_t blocking) {
+ isc_result_t result;
+ isc_time_t t;
+ isc_uint32_t sample;
+ isc_uint32_t extra;
+ unsigned char c;
+
+ UNUSED(arg);
+
+ if (!blocking)
+ return (ISC_R_NOTBLOCKING);
+
+ result = isc_keyboard_getchar(&source->kbd, &c);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ TIME_NOW(&t);
+
+ sample = isc_time_nanoseconds(&t);
+ extra = c;
+
+ result = isc_entropy_addcallbacksample(source, sample, extra);
+ if (result != ISC_R_SUCCESS) {
+ fprintf(stderr, "\r\n");
+ return (result);
+ }
+
+ fprintf(stderr, ".");
+ fflush(stderr);
+
+ return (result);
+}
+
+isc_result_t
+isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
+ const char *randomfile, int use_keyboard)
+{
+ isc_result_t result;
+ isc_result_t final_result = ISC_R_NOENTROPY;
+ isc_boolean_t userfile = ISC_TRUE;
+
+ REQUIRE(VALID_ENTROPY(ectx));
+ REQUIRE(source != NULL && *source == NULL);
+ REQUIRE(use_keyboard == ISC_ENTROPY_KEYBOARDYES ||
+ use_keyboard == ISC_ENTROPY_KEYBOARDNO ||
+ use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE);
+
+#ifdef PATH_RANDOMDEV
+ if (randomfile == NULL) {
+ randomfile = PATH_RANDOMDEV;
+ userfile = ISC_FALSE;
+ }
+#endif
+
+ if (randomfile != NULL && use_keyboard != ISC_ENTROPY_KEYBOARDYES) {
+ result = isc_entropy_createfilesource(ectx, randomfile);
+ if (result == ISC_R_SUCCESS &&
+ use_keyboard == ISC_ENTROPY_KEYBOARDMAYBE)
+ use_keyboard = ISC_ENTROPY_KEYBOARDNO;
+ if (result != ISC_R_SUCCESS && userfile)
+ return (result);
+
+ final_result = result;
+ }
+
+ if (use_keyboard != ISC_ENTROPY_KEYBOARDNO) {
+ result = isc_entropy_createcallbacksource(ectx, kbdstart,
+ kbdget, kbdstop,
+ NULL, source);
+ if (result == ISC_R_SUCCESS)
+ (*source)->warn_keyboard =
+ ISC_TF(use_keyboard ==
+ ISC_ENTROPY_KEYBOARDMAYBE);
+
+ if (final_result != ISC_R_SUCCESS)
+ final_result = result;
+ }
+
+ /*
+ * final_result is ISC_R_SUCCESS if at least one source of entropy
+ * could be started, otherwise it is the error from the most recently
+ * failed operation (or ISC_R_NOENTROPY if PATH_RANDOMDEV is not
+ * defined and use_keyboard is ISC_ENTROPY_KEYBOARDNO).
+ */
+ return (final_result);
+}
diff --git a/lib/isc/error.c b/lib/isc/error.c
new file mode 100644
index 000000000000..282986c46dd7
--- /dev/null
+++ b/lib/isc/error.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-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 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.17.18.2 2005/04/29 00:16:45 marka 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/lib/isc/event.c b/lib/isc/event.c
new file mode 100644
index 000000000000..7931061ac1f9
--- /dev/null
+++ b/lib/isc/event.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-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 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.17.18.2 2005/04/29 00:16:45 marka 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_t *mctx = event->ev_destroy_arg;
+
+ isc_mem_put(mctx, 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/lib/isc/fsaccess.c b/lib/isc/fsaccess.c
new file mode 100644
index 000000000000..cdab3d8fc1cc
--- /dev/null
+++ b/lib/isc/fsaccess.c
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: fsaccess.c,v 1.6.18.2 2005/04/29 00:16:45 marka Exp $ */
+
+/*! \file
+ * \brief
+ * This file contains the OS-independent functionality of the API.
+ */
+#include <isc/fsaccess.h>
+#include <isc/result.h>
+#include <isc/util.h>
+
+/*!
+ * Shorthand. Maybe ISC__FSACCESS_PERMISSIONBITS should not even be in
+ * <isc/fsaccess.h>. Could check consistency with sizeof(isc_fsaccess_t)
+ * and the number of bits in each function.
+ */
+#define STEP (ISC__FSACCESS_PERMISSIONBITS)
+#define GROUP (STEP)
+#define OTHER (STEP * 2)
+
+void
+isc_fsaccess_add(int trustee, int permission, isc_fsaccess_t *access) {
+ REQUIRE(trustee <= 0x7);
+ REQUIRE(permission <= 0xFF);
+
+ if ((trustee & ISC_FSACCESS_OWNER) != 0)
+ *access |= permission;
+
+ if ((trustee & ISC_FSACCESS_GROUP) != 0)
+ *access |= (permission << GROUP);
+
+ if ((trustee & ISC_FSACCESS_OTHER) != 0)
+ *access |= (permission << OTHER);
+}
+
+void
+isc_fsaccess_remove(int trustee, int permission, isc_fsaccess_t *access) {
+ REQUIRE(trustee <= 0x7);
+ REQUIRE(permission <= 0xFF);
+
+
+ if ((trustee & ISC_FSACCESS_OWNER) != 0)
+ *access &= ~permission;
+
+ if ((trustee & ISC_FSACCESS_GROUP) != 0)
+ *access &= ~(permission << GROUP);
+
+ if ((trustee & ISC_FSACCESS_OTHER) != 0)
+ *access &= ~(permission << OTHER);
+}
+
+static isc_result_t
+check_bad_bits(isc_fsaccess_t access, isc_boolean_t is_dir) {
+ isc_fsaccess_t bits;
+
+ /*
+ * Check for disallowed user bits.
+ */
+ if (is_dir)
+ bits = ISC_FSACCESS_READ |
+ ISC_FSACCESS_WRITE |
+ ISC_FSACCESS_EXECUTE;
+ else
+ bits = ISC_FSACCESS_CREATECHILD |
+ ISC_FSACCESS_ACCESSCHILD |
+ ISC_FSACCESS_DELETECHILD |
+ ISC_FSACCESS_LISTDIRECTORY;
+
+ /*
+ * Set group bad bits.
+ */
+ bits |= bits << STEP;
+ /*
+ * Set other bad bits.
+ */
+ bits |= bits << STEP;
+
+ if ((access & bits) != 0) {
+ if (is_dir)
+ return (ISC_R_NOTFILE);
+ else
+ return (ISC_R_NOTDIRECTORY);
+ }
+
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/isc/hash.c b/lib/isc/hash.c
new file mode 100644
index 000000000000..4b6dc06193f6
--- /dev/null
+++ b/lib/isc/hash.c
@@ -0,0 +1,390 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2003 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 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.c,v 1.6.18.5 2006/01/04 00:37:23 marka Exp $ */
+
+/*! \file
+ * Some portion of this code was derived from universal hash function
+ * libraries of Rice University.
+\section license UH Universal Hashing Library
+
+Copyright ((c)) 2002, Rice University
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ * 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.
+
+ * Neither the name of Rice University (RICE) 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 RICE and the contributors on an "as is"
+basis, without any representations or warranties of any kind, express
+or implied including, but not limited to, representations or
+warranties of non-infringement, merchantability or fitness for a
+particular purpose. In no event shall RICE 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.
+*/
+
+#include <config.h>
+
+#include <isc/entropy.h>
+#include <isc/hash.h>
+#include <isc/mem.h>
+#include <isc/magic.h>
+#include <isc/mutex.h>
+#include <isc/once.h>
+#include <isc/random.h>
+#include <isc/refcount.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#define HASH_MAGIC ISC_MAGIC('H', 'a', 's', 'h')
+#define VALID_HASH(h) ISC_MAGIC_VALID((h), HASH_MAGIC)
+
+/*%
+ * A large 32-bit prime number that specifies the range of the hash output.
+ */
+#define PRIME32 0xFFFFFFFB /* 2^32 - 5 */
+
+/*@{*/
+/*%
+ * Types of random seed and hash accumulator. Perhaps they can be system
+ * dependent.
+ */
+typedef isc_uint32_t hash_accum_t;
+typedef isc_uint16_t hash_random_t;
+/*@}*/
+
+/*% isc hash structure */
+struct isc_hash {
+ unsigned int magic;
+ isc_mem_t *mctx;
+ isc_mutex_t lock;
+ isc_boolean_t initialized;
+ isc_refcount_t refcnt;
+ isc_entropy_t *entropy; /*%< entropy source */
+ unsigned int limit; /*%< upper limit of key length */
+ size_t vectorlen; /*%< size of the vector below */
+ hash_random_t *rndvector; /*%< random vector for universal hashing */
+};
+
+static isc_mutex_t createlock;
+static isc_once_t once = ISC_ONCE_INIT;
+static isc_hash_t *hash = NULL;
+
+static unsigned char maptolower[] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+ 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+ 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+ 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+ 0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+ 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+ 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+ 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+ 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+ 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+ 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+ 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+ 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+ 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+ 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+ 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+ 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+ 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+ 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+ 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
+};
+
+isc_result_t
+isc_hash_ctxcreate(isc_mem_t *mctx, isc_entropy_t *entropy,
+ unsigned int limit, isc_hash_t **hctxp)
+{
+ isc_result_t result;
+ isc_hash_t *hctx;
+ size_t vlen;
+ hash_random_t *rv;
+ hash_accum_t overflow_limit;
+
+ REQUIRE(mctx != NULL);
+ REQUIRE(hctxp != NULL && *hctxp == NULL);
+
+ /*
+ * Overflow check. Since our implementation only does a modulo
+ * operation at the last stage of hash calculation, the accumulator
+ * must not overflow.
+ */
+ overflow_limit =
+ 1 << (((sizeof(hash_accum_t) - sizeof(hash_random_t))) * 8);
+ if (overflow_limit < (limit + 1) * 0xff)
+ return (ISC_R_RANGE);
+
+ hctx = isc_mem_get(mctx, sizeof(isc_hash_t));
+ if (hctx == NULL)
+ return (ISC_R_NOMEMORY);
+
+ vlen = sizeof(hash_random_t) * (limit + 1);
+ rv = isc_mem_get(mctx, vlen);
+ if (rv == NULL) {
+ result = ISC_R_NOMEMORY;
+ goto errout;
+ }
+
+ /*
+ * We need a lock.
+ */
+ result = isc_mutex_init(&hctx->lock);
+ if (result != ISC_R_SUCCESS)
+ goto errout;
+
+ /*
+ * From here down, no failures will/can occur.
+ */
+ hctx->magic = HASH_MAGIC;
+ hctx->mctx = NULL;
+ isc_mem_attach(mctx, &hctx->mctx);
+ hctx->initialized = ISC_FALSE;
+ result = isc_refcount_init(&hctx->refcnt, 1);
+ if (result != ISC_R_SUCCESS)
+ goto cleanup_lock;
+ hctx->entropy = NULL;
+ hctx->limit = limit;
+ hctx->vectorlen = vlen;
+ hctx->rndvector = rv;
+
+ if (entropy != NULL)
+ isc_entropy_attach(entropy, &hctx->entropy);
+
+ *hctxp = hctx;
+ return (ISC_R_SUCCESS);
+
+ cleanup_lock:
+ DESTROYLOCK(&hctx->lock);
+ errout:
+ isc_mem_put(mctx, hctx, sizeof(isc_hash_t));
+ if (rv != NULL)
+ isc_mem_put(mctx, rv, vlen);
+
+ return (result);
+}
+
+static void
+initialize_lock(void) {
+ RUNTIME_CHECK(isc_mutex_init(&createlock) == ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_hash_create(isc_mem_t *mctx, isc_entropy_t *entropy, size_t limit) {
+ isc_result_t result = ISC_R_SUCCESS;
+
+ REQUIRE(mctx != NULL);
+ INSIST(hash == NULL);
+
+ RUNTIME_CHECK(isc_once_do(&once, initialize_lock) == ISC_R_SUCCESS);
+
+ LOCK(&createlock);
+
+ if (hash == NULL)
+ result = isc_hash_ctxcreate(mctx, entropy, limit, &hash);
+
+ UNLOCK(&createlock);
+
+ return (result);
+}
+
+void
+isc_hash_ctxinit(isc_hash_t *hctx) {
+ isc_result_t result;
+
+ LOCK(&hctx->lock);
+
+ if (hctx->initialized == ISC_TRUE)
+ goto out;
+
+ if (hctx->entropy) {
+ result = isc_entropy_getdata(hctx->entropy,
+ hctx->rndvector, hctx->vectorlen,
+ NULL, 0);
+ INSIST(result == ISC_R_SUCCESS);
+ } else {
+ isc_uint32_t pr;
+ unsigned int i, copylen;
+ unsigned char *p;
+
+ p = (unsigned char *)hctx->rndvector;
+ for (i = 0; i < hctx->vectorlen; i += copylen, p += copylen) {
+ isc_random_get(&pr);
+ if (i + sizeof(pr) <= hctx->vectorlen)
+ copylen = sizeof(pr);
+ else
+ copylen = hctx->vectorlen - i;
+
+ memcpy(p, &pr, copylen);
+ }
+ INSIST(p == (unsigned char *)hctx->rndvector +
+ hctx->vectorlen);
+ }
+
+ hctx->initialized = ISC_TRUE;
+
+ out:
+ UNLOCK(&hctx->lock);
+}
+
+void
+isc_hash_init() {
+ INSIST(hash != NULL && VALID_HASH(hash));
+
+ isc_hash_ctxinit(hash);
+}
+
+void
+isc_hash_ctxattach(isc_hash_t *hctx, isc_hash_t **hctxp) {
+ REQUIRE(VALID_HASH(hctx));
+ REQUIRE(hctxp != NULL && *hctxp == NULL);
+
+ isc_refcount_increment(&hctx->refcnt, NULL);
+ *hctxp = hctx;
+}
+
+static void
+destroy(isc_hash_t **hctxp) {
+ isc_hash_t *hctx;
+ isc_mem_t *mctx;
+
+ REQUIRE(hctxp != NULL && *hctxp != NULL);
+ hctx = *hctxp;
+ *hctxp = NULL;
+
+ LOCK(&hctx->lock);
+
+ isc_refcount_destroy(&hctx->refcnt);
+
+ mctx = hctx->mctx;
+ if (hctx->entropy != NULL)
+ isc_entropy_detach(&hctx->entropy);
+ if (hctx->rndvector != NULL)
+ isc_mem_put(mctx, hctx->rndvector, hctx->vectorlen);
+
+ UNLOCK(&hctx->lock);
+
+ DESTROYLOCK(&hctx->lock);
+
+ memset(hctx, 0, sizeof(isc_hash_t));
+ isc_mem_put(mctx, hctx, sizeof(isc_hash_t));
+ isc_mem_detach(&mctx);
+}
+
+void
+isc_hash_ctxdetach(isc_hash_t **hctxp) {
+ isc_hash_t *hctx;
+ unsigned int refs;
+
+ REQUIRE(hctxp != NULL && VALID_HASH(*hctxp));
+ hctx = *hctxp;
+
+ isc_refcount_decrement(&hctx->refcnt, &refs);
+ if (refs == 0)
+ destroy(&hctx);
+
+ *hctxp = NULL;
+}
+
+void
+isc_hash_destroy() {
+ unsigned int refs;
+
+ INSIST(hash != NULL && VALID_HASH(hash));
+
+ isc_refcount_decrement(&hash->refcnt, &refs);
+ INSIST(refs == 0);
+
+ destroy(&hash);
+}
+
+static inline unsigned int
+hash_calc(isc_hash_t *hctx, const unsigned char *key, unsigned int keylen,
+ isc_boolean_t case_sensitive)
+{
+ hash_accum_t partial_sum = 0;
+ hash_random_t *p = hctx->rndvector;
+ unsigned int i = 0;
+
+ /* Make it sure that the hash context is initialized. */
+ if (hctx->initialized == ISC_FALSE)
+ isc_hash_ctxinit(hctx);
+
+ if (case_sensitive) {
+ for (i = 0; i < keylen; i++)
+ partial_sum += key[i] * (hash_accum_t)p[i];
+ } else {
+ for (i = 0; i < keylen; i++)
+ partial_sum += maptolower[key[i]] * (hash_accum_t)p[i];
+ }
+
+ partial_sum += p[i];
+
+ return ((unsigned int)(partial_sum % PRIME32));
+}
+
+unsigned int
+isc_hash_ctxcalc(isc_hash_t *hctx, const unsigned char *key,
+ unsigned int keylen, isc_boolean_t case_sensitive)
+{
+ REQUIRE(hctx != NULL && VALID_HASH(hctx));
+ REQUIRE(keylen <= hctx->limit);
+
+ return (hash_calc(hctx, key, keylen, case_sensitive));
+}
+
+unsigned int
+isc_hash_calc(const unsigned char *key, unsigned int keylen,
+ isc_boolean_t case_sensitive)
+{
+ INSIST(hash != NULL && VALID_HASH(hash));
+ REQUIRE(keylen <= hash->limit);
+
+ return (hash_calc(hash, key, keylen, case_sensitive));
+}
diff --git a/lib/isc/heap.c b/lib/isc/heap.c
new file mode 100644
index 000000000000..9c495a7404d7
--- /dev/null
+++ b/lib/isc/heap.c
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-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 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: heap.c,v 1.30.18.3 2006/04/17 18:27:33 explorer Exp $ */
+
+/*! \file
+ * Heap implementation of priority queues adapted from the following:
+ *
+ * \li "Introduction to Algorithms," Cormen, Leiserson, and Rivest,
+ * MIT Press / McGraw Hill, 1990, ISBN 0-262-03141-8, chapter 7.
+ *
+ * \li "Algorithms," Second Edition, Sedgewick, Addison-Wesley, 1988,
+ * ISBN 0-201-06673-4, chapter 11.
+ */
+
+#include <config.h>
+
+#include <isc/heap.h>
+#include <isc/magic.h>
+#include <isc/mem.h>
+#include <isc/string.h> /* Required for memcpy. */
+#include <isc/util.h>
+
+/*@{*/
+/*%
+ * Note: to make heap_parent and heap_left easy to compute, the first
+ * element of the heap array is not used; i.e. heap subscripts are 1-based,
+ * not 0-based. The parent is index/2, and the left-child is index*2.
+ * The right child is index*2+1.
+ */
+#define heap_parent(i) ((i) >> 1)
+#define heap_left(i) ((i) << 1)
+/*@}*/
+
+#define SIZE_INCREMENT 1024
+
+#define HEAP_MAGIC ISC_MAGIC('H', 'E', 'A', 'P')
+#define VALID_HEAP(h) ISC_MAGIC_VALID(h, HEAP_MAGIC)
+
+/*%
+ * When the heap is in a consistent state, the following invariant
+ * holds true: for every element i > 1, heap_parent(i) has a priority
+ * higher than or equal to that of i.
+ */
+#define HEAPCONDITION(i) ((i) == 1 || \
+ ! heap->compare(heap->array[(i)], \
+ heap->array[heap_parent(i)]))
+
+/*% ISC heap structure. */
+struct isc_heap {
+ unsigned int magic;
+ isc_mem_t * mctx;
+ unsigned int size;
+ unsigned int size_increment;
+ unsigned int last;
+ void **array;
+ isc_heapcompare_t compare;
+ isc_heapindex_t index;
+};
+
+isc_result_t
+isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare,
+ isc_heapindex_t index, unsigned int size_increment,
+ isc_heap_t **heapp)
+{
+ isc_heap_t *heap;
+
+ REQUIRE(heapp != NULL && *heapp == NULL);
+ REQUIRE(compare != NULL);
+
+ heap = isc_mem_get(mctx, sizeof(*heap));
+ if (heap == NULL)
+ return (ISC_R_NOMEMORY);
+ heap->magic = HEAP_MAGIC;
+ heap->mctx = mctx;
+ heap->size = 0;
+ if (size_increment == 0)
+ heap->size_increment = SIZE_INCREMENT;
+ else
+ heap->size_increment = size_increment;
+ heap->last = 0;
+ heap->array = NULL;
+ heap->compare = compare;
+ heap->index = index;
+
+ *heapp = heap;
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_heap_destroy(isc_heap_t **heapp) {
+ isc_heap_t *heap;
+
+ REQUIRE(heapp != NULL);
+ heap = *heapp;
+ REQUIRE(VALID_HEAP(heap));
+
+ if (heap->array != NULL)
+ isc_mem_put(heap->mctx, heap->array,
+ heap->size * sizeof(void *));
+ heap->magic = 0;
+ isc_mem_put(heap->mctx, heap, sizeof(*heap));
+
+ *heapp = NULL;
+}
+
+static isc_boolean_t
+resize(isc_heap_t *heap) {
+ void **new_array;
+ size_t new_size;
+
+ REQUIRE(VALID_HEAP(heap));
+
+ new_size = heap->size + heap->size_increment;
+ new_array = isc_mem_get(heap->mctx, new_size * sizeof(void *));
+ if (new_array == NULL)
+ return (ISC_FALSE);
+ if (heap->array != NULL) {
+ memcpy(new_array, heap->array, heap->size * sizeof(void *));
+ isc_mem_put(heap->mctx, heap->array,
+ heap->size * sizeof(void *));
+ }
+ heap->size = new_size;
+ heap->array = new_array;
+
+ return (ISC_TRUE);
+}
+
+static void
+float_up(isc_heap_t *heap, unsigned int i, void *elt) {
+ unsigned int p;
+
+ for (p = heap_parent(i) ;
+ i > 1 && heap->compare(elt, heap->array[p]) ;
+ i = p, p = heap_parent(i)) {
+ heap->array[i] = heap->array[p];
+ if (heap->index != NULL)
+ (heap->index)(heap->array[i], i);
+ }
+ heap->array[i] = elt;
+ if (heap->index != NULL)
+ (heap->index)(heap->array[i], i);
+
+ INSIST(HEAPCONDITION(i));
+}
+
+static void
+sink_down(isc_heap_t *heap, unsigned int i, void *elt) {
+ unsigned int j, size, half_size;
+ size = heap->last;
+ half_size = size / 2;
+ while (i <= half_size) {
+ /* Find the smallest of the (at most) two children. */
+ j = heap_left(i);
+ if (j < size && heap->compare(heap->array[j+1],
+ heap->array[j]))
+ j++;
+ if (heap->compare(elt, heap->array[j]))
+ break;
+ heap->array[i] = heap->array[j];
+ if (heap->index != NULL)
+ (heap->index)(heap->array[i], i);
+ i = j;
+ }
+ heap->array[i] = elt;
+ if (heap->index != NULL)
+ (heap->index)(heap->array[i], i);
+
+ INSIST(HEAPCONDITION(i));
+}
+
+isc_result_t
+isc_heap_insert(isc_heap_t *heap, void *elt) {
+ unsigned int i;
+
+ REQUIRE(VALID_HEAP(heap));
+
+ i = ++heap->last;
+ if (heap->last >= heap->size && !resize(heap))
+ return (ISC_R_NOMEMORY);
+
+ float_up(heap, i, elt);
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_heap_delete(isc_heap_t *heap, unsigned int index) {
+ void *elt;
+ isc_boolean_t less;
+
+ REQUIRE(VALID_HEAP(heap));
+ REQUIRE(index >= 1 && index <= heap->last);
+
+ if (index == heap->last) {
+ heap->last--;
+ } else {
+ elt = heap->array[heap->last--];
+ less = heap->compare(elt, heap->array[index]);
+ heap->array[index] = elt;
+ if (less)
+ float_up(heap, index, heap->array[index]);
+ else
+ sink_down(heap, index, heap->array[index]);
+ }
+}
+
+void
+isc_heap_increased(isc_heap_t *heap, unsigned int index) {
+ REQUIRE(VALID_HEAP(heap));
+ REQUIRE(index >= 1 && index <= heap->last);
+
+ float_up(heap, index, heap->array[index]);
+}
+
+void
+isc_heap_decreased(isc_heap_t *heap, unsigned int index) {
+ REQUIRE(VALID_HEAP(heap));
+ REQUIRE(index >= 1 && index <= heap->last);
+
+ sink_down(heap, index, heap->array[index]);
+}
+
+void *
+isc_heap_element(isc_heap_t *heap, unsigned int index) {
+ REQUIRE(VALID_HEAP(heap));
+ REQUIRE(index >= 1 && index <= heap->last);
+
+ return (heap->array[index]);
+}
+
+void
+isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap) {
+ unsigned int i;
+
+ REQUIRE(VALID_HEAP(heap));
+ REQUIRE(action != NULL);
+
+ for (i = 1 ; i <= heap->last ; i++)
+ (action)(heap->array[i], uap);
+}
diff --git a/lib/isc/hex.c b/lib/isc/hex.c
new file mode 100644
index 000000000000..8dfec0216fb8
--- /dev/null
+++ b/lib/isc/hex.c
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2003 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 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: hex.c,v 1.14.18.2 2005/04/29 00:16:46 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <ctype.h>
+
+#include <isc/buffer.h>
+#include <isc/hex.h>
+#include <isc/lex.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+#define RETERR(x) do { \
+ isc_result_t _r = (x); \
+ if (_r != ISC_R_SUCCESS) \
+ return (_r); \
+ } while (0)
+
+
+/*
+ * BEW: These static functions are copied from lib/dns/rdata.c.
+ */
+static isc_result_t
+str_totext(const char *source, isc_buffer_t *target);
+
+static isc_result_t
+mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length);
+
+static const char hex[] = "0123456789ABCDEF";
+
+isc_result_t
+isc_hex_totext(isc_region_t *source, int wordlength,
+ const char *wordbreak, isc_buffer_t *target)
+{
+ char buf[3];
+ unsigned int loops = 0;
+
+ if (wordlength < 2)
+ wordlength = 2;
+
+ memset(buf, 0, sizeof(buf));
+ while (source->length > 0) {
+ buf[0] = hex[(source->base[0] >> 4) & 0xf];
+ buf[1] = hex[(source->base[0]) & 0xf];
+ RETERR(str_totext(buf, target));
+ isc_region_consume(source, 1);
+
+ loops++;
+ if (source->length != 0 &&
+ (int)((loops + 1) * 2) >= wordlength)
+ {
+ loops = 0;
+ RETERR(str_totext(wordbreak, target));
+ }
+ }
+ return (ISC_R_SUCCESS);
+}
+
+/*%
+ * State of a hex decoding process in progress.
+ */
+typedef struct {
+ int length; /*%< Desired length of binary data or -1 */
+ isc_buffer_t *target; /*%< Buffer for resulting binary data */
+ int digits; /*%< Number of buffered hex digits */
+ int val[2];
+} hex_decode_ctx_t;
+
+static inline void
+hex_decode_init(hex_decode_ctx_t *ctx, int length, isc_buffer_t *target)
+{
+ ctx->digits = 0;
+ ctx->length = length;
+ ctx->target = target;
+}
+
+static inline isc_result_t
+hex_decode_char(hex_decode_ctx_t *ctx, int c) {
+ char *s;
+
+ if ((s = strchr(hex, toupper(c))) == NULL)
+ return (ISC_R_BADHEX);
+ ctx->val[ctx->digits++] = s - hex;
+ if (ctx->digits == 2) {
+ unsigned char num;
+
+ num = (ctx->val[0] << 4) + (ctx->val[1]);
+ RETERR(mem_tobuffer(ctx->target, &num, 1));
+ if (ctx->length >= 0) {
+ if (ctx->length == 0)
+ return (ISC_R_BADHEX);
+ else
+ ctx->length -= 1;
+ }
+ ctx->digits = 0;
+ }
+ return (ISC_R_SUCCESS);
+}
+
+static inline isc_result_t
+hex_decode_finish(hex_decode_ctx_t *ctx) {
+ if (ctx->length > 0)
+ return (ISC_R_UNEXPECTEDEND);
+ if (ctx->digits != 0)
+ return (ISC_R_BADHEX);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length) {
+ hex_decode_ctx_t ctx;
+ isc_textregion_t *tr;
+ isc_token_t token;
+ isc_boolean_t eol;
+
+ hex_decode_init(&ctx, length, target);
+
+ while (ctx.length != 0) {
+ unsigned int i;
+
+ if (length > 0)
+ eol = ISC_FALSE;
+ else
+ eol = ISC_TRUE;
+ RETERR(isc_lex_getmastertoken(lexer, &token,
+ isc_tokentype_string, eol));
+ if (token.type != isc_tokentype_string)
+ break;
+ tr = &token.value.as_textregion;
+ for (i = 0; i < tr->length; i++)
+ RETERR(hex_decode_char(&ctx, tr->base[i]));
+ }
+ if (ctx.length < 0)
+ isc_lex_ungettoken(lexer, &token);
+ RETERR(hex_decode_finish(&ctx));
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_hex_decodestring(char *cstr, isc_buffer_t *target) {
+ hex_decode_ctx_t ctx;
+
+ hex_decode_init(&ctx, -1, target);
+ for (;;) {
+ int c = *cstr++;
+ if (c == '\0')
+ break;
+ if (c == ' ' || c == '\t' || c == '\n' || c== '\r')
+ continue;
+ RETERR(hex_decode_char(&ctx, c));
+ }
+ RETERR(hex_decode_finish(&ctx));
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+str_totext(const char *source, isc_buffer_t *target) {
+ unsigned int l;
+ isc_region_t region;
+
+ isc_buffer_availableregion(target, &region);
+ l = strlen(source);
+
+ if (l > region.length)
+ return (ISC_R_NOSPACE);
+
+ memcpy(region.base, source, l);
+ isc_buffer_add(target, l);
+ return (ISC_R_SUCCESS);
+}
+
+static isc_result_t
+mem_tobuffer(isc_buffer_t *target, void *base, unsigned int length) {
+ isc_region_t tr;
+
+ isc_buffer_availableregion(target, &tr);
+ if (length > tr.length)
+ return (ISC_R_NOSPACE);
+ memcpy(tr.base, base, length);
+ isc_buffer_add(target, length);
+ return (ISC_R_SUCCESS);
+}
diff --git a/lib/isc/hmacmd5.c b/lib/isc/hmacmd5.c
new file mode 100644
index 000000000000..f83214644b53
--- /dev/null
+++ b/lib/isc/hmacmd5.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: hmacmd5.c,v 1.7.18.5 2006/02/26 22:30:56 marka Exp $ */
+
+/*! \file
+ * This code implements the HMAC-MD5 keyed hash algorithm
+ * described in RFC2104.
+ */
+
+#include "config.h"
+
+#include <isc/assertions.h>
+#include <isc/hmacmd5.h>
+#include <isc/md5.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#define PADLEN 64
+#define IPAD 0x36
+#define OPAD 0x5C
+
+/*!
+ * Start HMAC-MD5 process. Initialize an md5 context and digest the key.
+ */
+void
+isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[PADLEN];
+ int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_md5_t md5ctx;
+ isc_md5_init(&md5ctx);
+ isc_md5_update(&md5ctx, key, len);
+ isc_md5_final(&md5ctx, ctx->key);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_md5_init(&ctx->md5ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < PADLEN; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_md5_update(&ctx->md5ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx) {
+ isc_md5_invalidate(&ctx->md5ctx);
+ memset(ctx->key, 0, sizeof(ctx->key));
+}
+
+/*!
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_md5_update(&ctx->md5ctx, buf, len);
+}
+
+/*!
+ * Compute signature - finalize MD5 operation and reapply MD5.
+ */
+void
+isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest) {
+ unsigned char opad[PADLEN];
+ int i;
+
+ isc_md5_final(&ctx->md5ctx, digest);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < PADLEN; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_md5_init(&ctx->md5ctx);
+ isc_md5_update(&ctx->md5ctx, opad, sizeof(opad));
+ isc_md5_update(&ctx->md5ctx, digest, ISC_MD5_DIGESTLENGTH);
+ isc_md5_final(&ctx->md5ctx, digest);
+ isc_hmacmd5_invalidate(ctx);
+}
+
+/*!
+ * Verify signature - finalize MD5 operation and reapply MD5, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest) {
+ return (isc_hmacmd5_verify2(ctx, digest, ISC_MD5_DIGESTLENGTH));
+}
+
+isc_boolean_t
+isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_MD5_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_MD5_DIGESTLENGTH);
+ isc_hmacmd5_sign(ctx, newdigest);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
diff --git a/lib/isc/hmacsha.c b/lib/isc/hmacsha.c
new file mode 100644
index 000000000000..7ee13f773b13
--- /dev/null
+++ b/lib/isc/hmacsha.c
@@ -0,0 +1,438 @@
+/*
+ * Copyright (C) 2005-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: hmacsha.c,v 1.2.2.7 2007/08/28 07:20:06 tbox Exp $ */
+
+/*
+ * This code implements the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384
+ * and HMAC-SHA512 keyed hash algorithm described in RFC 2104 and
+ * draft-ietf-dnsext-tsig-sha-01.txt.
+ */
+
+#include "config.h"
+
+#include <isc/assertions.h>
+#include <isc/hmacsha.h>
+#include <isc/sha1.h>
+#include <isc/sha2.h>
+#include <isc/string.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+#define IPAD 0x36
+#define OPAD 0x5C
+
+/*
+ * Start HMAC-SHA1 process. Initialize an sha1 context and digest the key.
+ */
+void
+isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA1_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha1_t sha1ctx;
+ isc_sha1_init(&sha1ctx);
+ isc_sha1_update(&sha1ctx, key, len);
+ isc_sha1_final(&sha1ctx, ctx->key);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha1_init(&ctx->sha1ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha1_update(&ctx->sha1ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx) {
+ isc_sha1_invalidate(&ctx->sha1ctx);
+ memset(ctx->key, 0, sizeof(ctx->key));
+ memset(ctx, 0, sizeof(ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha1_update(&ctx->sha1ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA1 operation and reapply SHA1.
+ */
+void
+isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA1_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
+ isc_sha1_final(&ctx->sha1ctx, newdigest);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA1_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha1_init(&ctx->sha1ctx);
+ isc_sha1_update(&ctx->sha1ctx, opad, sizeof(opad));
+ isc_sha1_update(&ctx->sha1ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
+ isc_sha1_final(&ctx->sha1ctx, newdigest);
+ isc_hmacsha1_invalidate(ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Verify signature - finalize SHA1 operation and reapply SHA1, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA1_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA1_DIGESTLENGTH);
+ isc_hmacsha1_sign(ctx, newdigest, ISC_SHA1_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Start HMAC-SHA224 process. Initialize an sha224 context and digest the key.
+ */
+void
+isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA224_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha224_t sha224ctx;
+ isc_sha224_init(&sha224ctx);
+ isc_sha224_update(&sha224ctx, key, len);
+ isc_sha224_final(ctx->key, &sha224ctx);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha224_init(&ctx->sha224ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha224_update(&ctx->sha224ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx) {
+ memset(ctx->key, 0, sizeof(ctx->key));
+ memset(ctx, 0, sizeof(ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha224_update(&ctx->sha224ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA224 operation and reapply SHA224.
+ */
+void
+isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA224_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
+ isc_sha224_final(newdigest, &ctx->sha224ctx);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA224_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha224_init(&ctx->sha224ctx);
+ isc_sha224_update(&ctx->sha224ctx, opad, sizeof(opad));
+ isc_sha224_update(&ctx->sha224ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
+ isc_sha224_final(newdigest, &ctx->sha224ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Verify signature - finalize SHA224 operation and reapply SHA224, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA224_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA224_DIGESTLENGTH);
+ isc_hmacsha224_sign(ctx, newdigest, ISC_SHA224_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Start HMAC-SHA256 process. Initialize an sha256 context and digest the key.
+ */
+void
+isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA256_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha256_t sha256ctx;
+ isc_sha256_init(&sha256ctx);
+ isc_sha256_update(&sha256ctx, key, len);
+ isc_sha256_final(ctx->key, &sha256ctx);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha256_init(&ctx->sha256ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha256_update(&ctx->sha256ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx) {
+ memset(ctx->key, 0, sizeof(ctx->key));
+ memset(ctx, 0, sizeof(ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha256_update(&ctx->sha256ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA256 operation and reapply SHA256.
+ */
+void
+isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA256_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
+ isc_sha256_final(newdigest, &ctx->sha256ctx);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA256_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha256_init(&ctx->sha256ctx);
+ isc_sha256_update(&ctx->sha256ctx, opad, sizeof(opad));
+ isc_sha256_update(&ctx->sha256ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
+ isc_sha256_final(newdigest, &ctx->sha256ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Verify signature - finalize SHA256 operation and reapply SHA256, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA256_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA256_DIGESTLENGTH);
+ isc_hmacsha256_sign(ctx, newdigest, ISC_SHA256_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Start HMAC-SHA384 process. Initialize an sha384 context and digest the key.
+ */
+void
+isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA384_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha384_t sha384ctx;
+ isc_sha384_init(&sha384ctx);
+ isc_sha384_update(&sha384ctx, key, len);
+ isc_sha384_final(ctx->key, &sha384ctx);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha384_init(&ctx->sha384ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha384_update(&ctx->sha384ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx) {
+ memset(ctx->key, 0, sizeof(ctx->key));
+ memset(ctx, 0, sizeof(ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha384_update(&ctx->sha384ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA384 operation and reapply SHA384.
+ */
+void
+isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA384_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
+ isc_sha384_final(newdigest, &ctx->sha384ctx);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA384_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha384_init(&ctx->sha384ctx);
+ isc_sha384_update(&ctx->sha384ctx, opad, sizeof(opad));
+ isc_sha384_update(&ctx->sha384ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
+ isc_sha384_final(newdigest, &ctx->sha384ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Verify signature - finalize SHA384 operation and reapply SHA384, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA384_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA384_DIGESTLENGTH);
+ isc_hmacsha384_sign(ctx, newdigest, ISC_SHA384_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
+
+/*
+ * Start HMAC-SHA512 process. Initialize an sha512 context and digest the key.
+ */
+void
+isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
+ unsigned int len)
+{
+ unsigned char ipad[ISC_SHA512_BLOCK_LENGTH];
+ unsigned int i;
+
+ memset(ctx->key, 0, sizeof(ctx->key));
+ if (len > sizeof(ctx->key)) {
+ isc_sha512_t sha512ctx;
+ isc_sha512_init(&sha512ctx);
+ isc_sha512_update(&sha512ctx, key, len);
+ isc_sha512_final(ctx->key, &sha512ctx);
+ } else
+ memcpy(ctx->key, key, len);
+
+ isc_sha512_init(&ctx->sha512ctx);
+ memset(ipad, IPAD, sizeof(ipad));
+ for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
+ ipad[i] ^= ctx->key[i];
+ isc_sha512_update(&ctx->sha512ctx, ipad, sizeof(ipad));
+}
+
+void
+isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx) {
+ memset(ctx->key, 0, sizeof(ctx->key));
+ memset(ctx, 0, sizeof(ctx));
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
+ unsigned int len)
+{
+ isc_sha512_update(&ctx->sha512ctx, buf, len);
+}
+
+/*
+ * Compute signature - finalize SHA512 operation and reapply SHA512.
+ */
+void
+isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char opad[ISC_SHA512_BLOCK_LENGTH];
+ unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
+ unsigned int i;
+
+ REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
+ isc_sha512_final(newdigest, &ctx->sha512ctx);
+
+ memset(opad, OPAD, sizeof(opad));
+ for (i = 0; i < ISC_SHA512_BLOCK_LENGTH; i++)
+ opad[i] ^= ctx->key[i];
+
+ isc_sha512_init(&ctx->sha512ctx);
+ isc_sha512_update(&ctx->sha512ctx, opad, sizeof(opad));
+ isc_sha512_update(&ctx->sha512ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
+ isc_sha512_final(newdigest, &ctx->sha512ctx);
+ memcpy(digest, newdigest, len);
+ memset(newdigest, 0, sizeof(newdigest));
+}
+
+/*
+ * Verify signature - finalize SHA512 operation and reapply SHA512, then
+ * compare to the supplied digest.
+ */
+isc_boolean_t
+isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len) {
+ unsigned char newdigest[ISC_SHA512_DIGESTLENGTH];
+
+ REQUIRE(len <= ISC_SHA512_DIGESTLENGTH);
+ isc_hmacsha512_sign(ctx, newdigest, ISC_SHA512_DIGESTLENGTH);
+ return (ISC_TF(memcmp(digest, newdigest, len) == 0));
+}
diff --git a/lib/isc/ia64/Makefile.in b/lib/isc/ia64/Makefile.in
new file mode 100644
index 000000000000..c8e77e43365c
--- /dev/null
+++ b/lib/isc/ia64/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 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: Makefile.in,v 1.2.2.1 2007/09/14 04:26:38 marka Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = include
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/isc/ia64/include/Makefile.in b/lib/isc/ia64/include/Makefile.in
new file mode 100644
index 000000000000..f4dd2f650c95
--- /dev/null
+++ b/lib/isc/ia64/include/Makefile.in
@@ -0,0 +1,24 @@
+# Copyright (C) 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: Makefile.in,v 1.2.2.1 2007/09/14 04:26:38 marka Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/isc/ia64/include/isc/Makefile.in b/lib/isc/ia64/include/isc/Makefile.in
new file mode 100644
index 000000000000..6760ce61d743
--- /dev/null
+++ b/lib/isc/ia64/include/isc/Makefile.in
@@ -0,0 +1,36 @@
+# Copyright (C) 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: Makefile.in,v 1.2.2.1 2007/09/14 04:26:38 marka Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+HEADERS = atomic.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} $(srcdir)/$$i ${DESTDIR}${includedir}/isc ; \
+ done
diff --git a/lib/isc/ia64/include/isc/atomic.h b/lib/isc/ia64/include/isc/atomic.h
new file mode 100644
index 000000000000..20cbabdae394
--- /dev/null
+++ b/lib/isc/ia64/include/isc/atomic.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2006 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * 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 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: atomic.h,v 1.2.2.1 2006/06/21 03:38:32 marka Exp $ */
+
+#ifndef ISC_ATOMIC_H
+#define ISC_ATOMIC_H 1
+
+#include <isc/platform.h>
+#include <isc/types.h>
+
+#ifdef ISC_PLATFORM_USEGCCASM
+/*
+ * This routine atomically increments the value stored in 'p' by 'val', and
+ * returns the previous value.
+ *
+ * Open issue: can 'fetchadd' make the code faster for some particular values
+ * (e.g., 1 and -1)?
+ */
+static inline isc_int32_t
+isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
+ isc_int32_t prev, swapped;
+
+ for (prev = *(volatile isc_int32_t *)p; ; prev = swapped) {
+ swapped = prev + val;
+ __asm__ volatile(
+ "mov ar.ccv=%2;"
+ "cmpxchg4.acq %0=%4,%3,ar.ccv"
+ : "=r" (swapped), "=m" (*p)
+ : "r" (prev), "r" (swapped), "m" (*p)
+ : "memory");
+ if (swapped == prev)
+ break;
+ }
+
+ return (prev);
+}
+
+/*
+ * This routine atomically stores the value 'val' in 'p'.
+ */
+static inline void
+isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
+ __asm__ volatile(
+ "st4.rel %0=%1"
+ : "=m" (*p)
+ : "r" (val)
+ : "memory"
+ );
+}
+
+/*
+ * This routine atomically replaces the value in 'p' with 'val', if the
+ * original value is equal to 'cmpval'. The original value is returned in any
+ * case.
+ */
+static inline isc_int32_t
+isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
+ isc_int32_t ret;
+
+ __asm__ volatile(
+ "mov ar.ccv=%2;"
+ "cmpxchg4.acq %0=%4,%3,ar.ccv"
+ : "=r" (ret), "=m" (*p)
+ : "r" (cmpval), "r" (val), "m" (*p)
+ : "memory");
+
+ return (ret);
+}
+#else /* !ISC_PLATFORM_USEGCCASM */
+
+#error "unsupported compiler. disable atomic ops by --disable-atomic"
+
+#endif
+#endif /* ISC_ATOMIC_H */
diff --git a/lib/isc/include/Makefile.in b/lib/isc/include/Makefile.in
new file mode 100644
index 000000000000..ceb8eb6061fd
--- /dev/null
+++ b/lib/isc/include/Makefile.in
@@ -0,0 +1,25 @@
+# Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 1998-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 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: Makefile.in,v 1.11 2004/03/05 05:10:53 marka Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+SUBDIRS = isc
+TARGETS =
+
+@BIND9_MAKE_RULES@
diff --git a/lib/isc/include/isc/Makefile.in b/lib/isc/include/isc/Makefile.in
new file mode 100644
index 000000000000..0f0e93611653
--- /dev/null
+++ b/lib/isc/include/isc/Makefile.in
@@ -0,0 +1,57 @@
+# Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+# Copyright (C) 1998-2001, 2003 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 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: Makefile.in,v 1.54.18.4 2006/01/27 23:57:45 marka Exp $
+
+srcdir = @srcdir@
+VPATH = @srcdir@
+top_srcdir = @top_srcdir@
+
+@BIND9_VERSION@
+
+#
+# Only list headers that are to be installed and are not
+# machine generated. The latter are handled specially in the
+# install target below.
+#
+HEADERS = app.h assertions.h base64.h bitstring.h boolean.h buffer.h \
+ bufferlist.h commandline.h entropy.h error.h event.h \
+ eventclass.h file.h formatcheck.h fsaccess.h \
+ hash.h heap.h hex.h hmacmd5.h \
+ interfaceiter.h @ISC_IPV6_H@ lang.h lex.h \
+ lfsr.h lib.h list.h log.h magic.h md5.h mem.h msgcat.h msgs.h \
+ mutexblock.h netaddr.h ondestroy.h os.h parseint.h \
+ print.h quota.h random.h ratelimiter.h \
+ refcount.h region.h resource.h \
+ result.h resultclass.h rwlock.h serial.h sha1.h sha2.h \
+ sockaddr.h socket.h stdio.h stdlib.h string.h symtab.h \
+ task.h taskpool.h timer.h types.h util.h version.h
+
+SUBDIRS =
+TARGETS =
+
+@BIND9_MAKE_RULES@
+
+installdirs:
+ $(SHELL) ${top_srcdir}/mkinstalldirs ${DESTDIR}${includedir}/isc
+
+install:: installdirs
+ for i in ${HEADERS}; do \
+ ${INSTALL_DATA} ${srcdir}/$$i ${DESTDIR}${includedir}/isc ; \
+ done
+ ${INSTALL_DATA} platform.h ${DESTDIR}${includedir}/isc
+
+distclean::
+ rm -f platform.h
diff --git a/lib/isc/include/isc/app.h b/lib/isc/include/isc/app.h
new file mode 100644
index 000000000000..f51aff73e2a7
--- /dev/null
+++ b/lib/isc/include/isc/app.h
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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.2.18.2 2005/04/29 00:16:52 marka Exp $ */
+
+#ifndef ISC_APP_H
+#define ISC_APP_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \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.
+ *
+ * \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).
+ *
+ * \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/result.h>
+
+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)
+
+ISC_LANG_BEGINDECLS
+
+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.
+ */
+
+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:
+ * isc_app_start() has been called.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * ISC_R_NOMEMORY
+ */
+
+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_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.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS Shutdown has been requested.
+ *\li ISC_R_RELOAD Reload has been requested.
+ */
+
+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_run() has been called.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS
+ *\li ISC_R_UNEXPECTED
+ */
+
+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_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.
+ *
+ * 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_LANG_ENDDECLS
+
+#endif /* ISC_APP_H */
diff --git a/lib/isc/include/isc/assertions.h b/lib/isc/include/isc/assertions.h
new file mode 100644
index 000000000000..c1e68a127a2e
--- /dev/null
+++ b/lib/isc/include/isc/assertions.h
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-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 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.18.18.2 2005/04/29 00:16:52 marka Exp $
+ */
+/*! \file 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 *);
+
+LIBISC_EXTERNAL_DATA extern isc_assertioncallback_t isc_assertion_failed;
+
+void
+isc_assertion_setcallback(isc_assertioncallback_t);
+
+const char *
+isc_assertion_typetotext(isc_assertiontype_t type);
+
+#ifdef ISC_CHECK_ALL
+#define ISC_CHECK_REQUIRE 1
+#define ISC_CHECK_ENSURE 1
+#define ISC_CHECK_INSIST 1
+#define ISC_CHECK_INVARIANT 1
+#endif
+
+#ifdef ISC_CHECK_NONE
+#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/lib/isc/include/isc/base64.h b/lib/isc/include/isc/base64.h
new file mode 100644
index 000000000000..26ffa488bfea
--- /dev/null
+++ b/lib/isc/include/isc/base64.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: base64.h,v 1.16.18.2 2005/04/29 00:16:53 marka Exp $ */
+
+#ifndef ISC_BASE64_H
+#define ISC_BASE64_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_base64_totext(isc_region_t *source, int wordlength,
+ const char *wordbreak, isc_buffer_t *target);
+/*!<
+ * \brief Convert data into base64 encoded text.
+ *
+ * Notes:
+ *\li The base64 encoded text in 'target' will be divided into
+ * words of at most 'wordlength' characters, separated by
+ * the 'wordbreak' string. No parentheses will surround
+ * the text.
+ *
+ * Requires:
+ *\li 'source' is a region containing binary data
+ *\li 'target' is a text buffer containing available space
+ *\li 'wordbreak' points to a null-terminated string of
+ * zero or more whitespace characters
+ *
+ * Ensures:
+ *\li target will contain the base64 encoded version of the data
+ * in source. The 'used' pointer in target will be advanced as
+ * necessary.
+ */
+
+isc_result_t
+isc_base64_decodestring(const char *cstr, isc_buffer_t *target);
+/*!<
+ * \brief Decode a null-terminated base64 string.
+ *
+ * Requires:
+ *\li 'cstr' is non-null.
+ *\li 'target' is a valid buffer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring'
+ * fit in 'target'.
+ *\li #ISC_R_BADBASE64 -- 'cstr' is not a valid base64 encoding.
+ *
+ * Other error returns are any possible error code from:
+ *\li isc_lex_create(),
+ *\li isc_lex_openbuffer(),
+ *\li isc_base64_tobuffer().
+ */
+
+isc_result_t
+isc_base64_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
+/*!<
+ * \brief Convert base64 encoded text from a lexer context into data.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer context
+ *\li 'target' is a buffer containing binary data
+ *\li 'length' is an integer
+ *
+ * Ensures:
+ *\li target will contain the data represented by the base64 encoded
+ * string parsed by the lexer. No more than length bytes will be read,
+ * if length is positive. The 'used' pointer in target will be
+ * advanced as necessary.
+ */
+
+
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BASE64_H */
diff --git a/lib/isc/include/isc/bitstring.h b/lib/isc/include/isc/bitstring.h
new file mode 100644
index 000000000000..3e626b8b06b7
--- /dev/null
+++ b/lib/isc/include/isc/bitstring.h
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: bitstring.h,v 1.8.18.2 2005/04/29 00:16:53 marka Exp $ */
+
+#ifndef ISC_BITSTRING_H
+#define ISC_BITSTRING_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file bitstring.h
+ *
+ * \brief Bitstring manipulation functions.
+ *
+ * A bitstring is a packed array of bits, stored in a contiguous
+ * sequence of octets. The "most significant bit" (msb) of a bitstring
+ * is the high bit of the first octet. The "least significant bit" of a
+ * bitstring is the low bit of the last octet.
+ *
+ * Two bit numbering schemes are supported, "msb0" and "lsb0".
+ *
+ * In the "msb0" scheme, bit number 0 designates the most significant bit,
+ * and any padding bits required to make the bitstring a multiple of 8 bits
+ * long are added to the least significant end of the last octet.
+ *
+ * In the "lsb0" scheme, bit number 0 designates the least significant bit,
+ * and any padding bits required to make the bitstring a multiple of 8 bits
+ * long are added to the most significant end of the first octet.
+ *
+ * E.g., consider the bitstring "11010001111". This bitstring is 11 bits
+ * long and will take two octets. Let "p" denote a pad bit. In the msb0
+ * encoding, it would be
+ *
+ * \verbatim
+ * Octet 0 Octet 1
+ * |
+ * 1 1 0 1 0 0 0 1 | 1 1 1 p p p p p
+ * ^ | ^
+ * | |
+ * bit 0 bit 15
+ * \endverbatim
+ *
+ * In the lsb0 encoding, it would be
+ *
+ * \verbatim
+ * Octet 0 Octet 1
+ * |
+ * p p p p p 1 1 0 | 1 0 0 0 1 1 1 1
+ * ^ | ^
+ * | |
+ * bit 15 bit 0
+ * \endverbatim
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Types
+ ***/
+
+struct isc_bitstring {
+ unsigned int magic;
+ unsigned char * data;
+ unsigned int length;
+ unsigned int size;
+ isc_boolean_t lsb0;
+};
+
+/***
+ *** Functions
+ ***/
+
+void
+isc_bitstring_init(isc_bitstring_t *bitstring, unsigned char *data,
+ unsigned int length, unsigned int size, isc_boolean_t lsb0);
+/*!<
+ * \brief Make 'bitstring' refer to the bitstring of 'size' bits starting
+ * at 'data'. 'length' bits of the bitstring are valid. If 'lsb0'
+ * is set then, bit 0 refers to the least significant bit of the
+ * bitstring. Otherwise bit 0 is the most significant bit.
+ *
+ * Requires:
+ *
+ *\li 'bitstring' points to a isc_bitstring_t.
+ *
+ *\li 'data' points to an array of unsigned char large enough to hold
+ * 'size' bits.
+ *
+ *\li 'length' <= 'size'.
+ *
+ * Ensures:
+ *
+ *\li 'bitstring' is a valid bitstring.
+ */
+
+void
+isc_bitstring_invalidate(isc_bitstring_t *bitstring);
+/*!<
+ * \brief Invalidate 'bitstring'.
+ *
+ * Requires:
+ *
+ *\li 'bitstring' is a valid bitstring.
+ *
+ * Ensures:
+ *
+ *\li 'bitstring' is not a valid bitstring.
+ */
+
+void
+isc_bitstring_copy(isc_bitstring_t *source, unsigned int sbitpos,
+ isc_bitstring_t *target, unsigned int tbitpos,
+ unsigned int n);
+/*!<
+ * \brief Starting at bit 'sbitpos', copy 'n' bits from 'source' to
+ * the 'n' bits of 'target' starting at 'tbitpos'.
+ *
+ * Requires:
+ *
+ *\li 'source' and target are valid bitstrings with the same lsb0 setting.
+ *
+ *\li 'sbitpos' + 'n' is less than or equal to the length of 'source'.
+ *
+ *\li 'tbitpos' + 'n' is less than or equal to the size of 'target'.
+ *
+ * Ensures:
+ *
+ *\li The specified bits have been copied, and the length of 'target'
+ * adjusted (if required).
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BITSTRING_H */
diff --git a/lib/isc/include/isc/boolean.h b/lib/isc/include/isc/boolean.h
new file mode 100644
index 000000000000..ad736fe69823
--- /dev/null
+++ b/lib/isc/include/isc/boolean.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-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 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.13.18.2 2005/04/29 00:16:53 marka Exp $ */
+
+#ifndef ISC_BOOLEAN_H
+#define ISC_BOOLEAN_H 1
+
+/*! \file */
+
+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/lib/isc/include/isc/buffer.h b/lib/isc/include/isc/buffer.h
new file mode 100644
index 000000000000..a285e27983b4
--- /dev/null
+++ b/lib/isc/include/isc/buffer.h
@@ -0,0 +1,811 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 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 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.43.18.2 2005/04/29 00:16:53 marka Exp $ */
+
+#ifndef ISC_BUFFER_H
+#define ISC_BUFFER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file 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_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.
+ */
+
+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_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_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_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_putuint32 ISC__BUFFER_PUTUINT32
+#else
+#define isc_buffer_init isc__buffer_init
+#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_putuint32 isc__buffer_putuint32
+#endif
+
+#endif /* ISC_BUFFER_H */
diff --git a/lib/isc/include/isc/bufferlist.h b/lib/isc/include/isc/bufferlist.h
new file mode 100644
index 000000000000..7fc2ecc0a599
--- /dev/null
+++ b/lib/isc/include/isc/bufferlist.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: bufferlist.h,v 1.11.18.2 2005/04/29 00:16:53 marka Exp $ */
+
+#ifndef ISC_BUFFERLIST_H
+#define ISC_BUFFERLIST_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file bufferlist.h
+ *
+ *
+ *\brief Buffer lists have no synchronization. Clients must ensure exclusive
+ * access.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+unsigned int
+isc_bufferlist_usedcount(isc_bufferlist_t *bl);
+/*!<
+ * \brief Return the length of the sum of all used regions of all buffers in
+ * the buffer list 'bl'
+ *
+ * Requires:
+ *
+ *\li 'bl' is not NULL.
+ *
+ * Returns:
+ *\li sum of all used regions' lengths.
+ */
+
+unsigned int
+isc_bufferlist_availablecount(isc_bufferlist_t *bl);
+/*!<
+ * \brief Return the length of the sum of all available regions of all buffers in
+ * the buffer list 'bl'
+ *
+ * Requires:
+ *
+ *\li 'bl' is not NULL.
+ *
+ * Returns:
+ *\li sum of all available regions' lengths.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_BUFFERLIST_H */
diff --git a/lib/isc/include/isc/commandline.h b/lib/isc/include/isc/commandline.h
new file mode 100644
index 000000000000..5ece26f73d43
--- /dev/null
+++ b/lib/isc/include/isc/commandline.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: commandline.h,v 1.10.18.2 2005/04/29 00:16:53 marka Exp $ */
+
+#ifndef ISC_COMMANDLINE_H
+#define ISC_COMMANDLINE_H 1
+
+/*! \file */
+
+#include <isc/boolean.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+/*% Index into parent argv vector. */
+LIBISC_EXTERNAL_DATA extern int isc_commandline_index;
+/*% Character checked for validity. */
+LIBISC_EXTERNAL_DATA extern int isc_commandline_option;
+/*% Argument associated with option. */
+LIBISC_EXTERNAL_DATA extern char *isc_commandline_argument;
+/*% For printing error messages. */
+LIBISC_EXTERNAL_DATA extern char *isc_commandline_progname;
+/*% Print error message. */
+LIBISC_EXTERNAL_DATA extern isc_boolean_t isc_commandline_errprint;
+/*% Reset getopt. */
+LIBISC_EXTERNAL_DATA extern isc_boolean_t isc_commandline_reset;
+
+ISC_LANG_BEGINDECLS
+
+/*% parse command line */
+int
+isc_commandline_parse(int argc, char * const *argv, const char *options);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_COMMANDLINE_H */
diff --git a/lib/isc/include/isc/entropy.h b/lib/isc/include/isc/entropy.h
new file mode 100644
index 000000000000..2890f6c5c270
--- /dev/null
+++ b/lib/isc/include/isc/entropy.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: entropy.h,v 1.25.18.2 2005/04/29 00:16:54 marka Exp $ */
+
+#ifndef ISC_ENTROPY_H
+#define ISC_ENTROPY_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file entropy.h
+ * \brief The entropy API
+ *
+ * \li MP:
+ * The entropy object is locked internally. All callbacks into
+ * application-provided functions (for setup, gathering, and
+ * shutdown of sources) are guaranteed to be called with the
+ * entropy API lock held. This means these functions are
+ * not permitted to call back into the entropy API.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * A buffer, used as an entropy pool.
+ *
+ * \li Security:
+ * While this code is believed to implement good entropy gathering
+ * and distribution, it has not been reviewed by a cryptographic
+ * expert.
+ * Since the added entropy is only as good as the sources used,
+ * this module could hand out bad data and never know it.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*@{*/
+/*% Entropy callback function. */
+typedef isc_result_t (*isc_entropystart_t)(isc_entropysource_t *source,
+ void *arg, isc_boolean_t blocking);
+typedef isc_result_t (*isc_entropyget_t)(isc_entropysource_t *source,
+ void *arg, isc_boolean_t blocking);
+typedef void (*isc_entropystop_t)(isc_entropysource_t *source, void *arg);
+/*@}*/
+
+/***
+ *** Flags.
+ ***/
+
+/*!
+ * \brief
+ * Extract only "good" data; return failure if there is not enough
+ * data available and there are no sources which we can poll to get
+ * data, or those sources are empty.
+ *
+ *
+ */
+#define ISC_ENTROPY_GOODONLY 0x00000001U
+/*!
+ * \brief
+ * Extract as much good data as possible, but if there isn't enough
+ * at hand, return what is available. This flag only makes sense
+ * when used with _GOODONLY.
+ */
+#define ISC_ENTROPY_PARTIAL 0x00000002U
+/*!
+ * \brief
+ * Block the task until data is available. This is contrary to the
+ * ISC task system, where tasks should never block. However, if
+ * this is a special purpose application where blocking a task is
+ * acceptable (say, an offline zone signer) this flag may be set.
+ * This flag only makes sense when used with _GOODONLY, and will
+ * block regardless of the setting for _PARTIAL.
+ */
+#define ISC_ENTROPY_BLOCKING 0x00000004U
+
+/*!
+ * \brief
+ * Estimate the amount of entropy contained in the sample pool.
+ * If this is not set, the source will be gathered and perodically
+ * mixed into the entropy pool, but no increment in contained entropy
+ * will be assumed. This flag only makes sense on sample sources.
+ */
+#define ISC_ENTROPYSOURCE_ESTIMATE 0x00000001U
+
+/*
+ * For use with isc_entropy_usebestsource().
+ */
+/*!
+ * \brief
+ * Use the keyboard as the only entropy source.
+ */
+#define ISC_ENTROPY_KEYBOARDYES 1
+/*!
+ * \brief
+ * Never use the keyboard as an entropy source.
+ */
+#define ISC_ENTROPY_KEYBOARDNO 2
+/*!
+ * \brief
+ * Use the keyboard as an entropy source only if opening the
+ * random device fails.
+ */
+#define ISC_ENTROPY_KEYBOARDMAYBE 3
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_entropy_create(isc_mem_t *mctx, isc_entropy_t **entp);
+/*!<
+ * \brief Create a new entropy object.
+ */
+
+void
+isc_entropy_attach(isc_entropy_t *ent, isc_entropy_t **entp);
+/*!<
+ * Attaches to an entropy object.
+ */
+
+void
+isc_entropy_detach(isc_entropy_t **entp);
+/*!<
+ * \brief Detaches from an entropy object.
+ */
+
+isc_result_t
+isc_entropy_createfilesource(isc_entropy_t *ent, const char *fname);
+/*!<
+ * \brief Create a new entropy source from a file.
+ *
+ * The file is assumed to contain good randomness, and will be mixed directly
+ * into the pool with every byte adding 8 bits of entropy.
+ *
+ * The file will be put into non-blocking mode, so it may be a device file,
+ * such as /dev/random. /dev/urandom should not be used here if it can
+ * be avoided, since it will always provide data even if it isn't good.
+ * We will make as much pseudorandom data as we need internally if our
+ * caller asks for it.
+ *
+ * If we hit end-of-file, we will stop reading from this source. Callers
+ * who require strong random data will get failure when our pool drains.
+ * The file will never be opened/read again once EOF is reached.
+ */
+
+void
+isc_entropy_destroysource(isc_entropysource_t **sourcep);
+/*!<
+ * \brief Removes an entropy source from the entropy system.
+ */
+
+isc_result_t
+isc_entropy_createsamplesource(isc_entropy_t *ent,
+ isc_entropysource_t **sourcep);
+/*!<
+ * \brief Create an entropy source that consists of samples. Each sample is added
+ * to the source via isc_entropy_addsamples(), below.
+ */
+
+isc_result_t
+isc_entropy_createcallbacksource(isc_entropy_t *ent,
+ isc_entropystart_t start,
+ isc_entropyget_t get,
+ isc_entropystop_t stop,
+ void *arg,
+ isc_entropysource_t **sourcep);
+/*!<
+ * \brief Create an entropy source that is polled via a callback.
+ *
+ * This would
+ * be used when keyboard input is used, or a GUI input method. It can
+ * also be used to hook in any external entropy source.
+ *
+ * Samples are added via isc_entropy_addcallbacksample(), below.
+ * _addcallbacksample() is the only function which may be called from
+ * within an entropy API callback function.
+ */
+
+void
+isc_entropy_stopcallbacksources(isc_entropy_t *ent);
+/*!<
+ * \brief Call the stop functions for callback sources that have had their
+ * start functions called.
+ */
+
+/*@{*/
+isc_result_t
+isc_entropy_addcallbacksample(isc_entropysource_t *source, isc_uint32_t sample,
+ isc_uint32_t extra);
+isc_result_t
+isc_entropy_addsample(isc_entropysource_t *source, isc_uint32_t sample,
+ isc_uint32_t extra);
+/*!<
+ * \brief Add a sample to the sample source.
+ *
+ * The sample MUST be a timestamp
+ * that increases over time, with the exception of wrap-around for
+ * extremely high resolution timers which will quickly wrap-around
+ * a 32-bit integer.
+ *
+ * The "extra" parameter is used only to add a bit more unpredictable
+ * data. It is not used other than included in the hash of samples.
+ *
+ * When in an entropy API callback function, _addcallbacksource() must be
+ * used. At all other times, _addsample() must be used.
+ */
+/*@}*/
+
+isc_result_t
+isc_entropy_getdata(isc_entropy_t *ent, void *data, unsigned int length,
+ unsigned int *returned, unsigned int flags);
+/*!<
+ * \brief Extract data from the entropy pool. This may load the pool from various
+ * sources.
+ *
+ * Do this by stiring the pool and returning a part of hash as randomness.
+ * Note that no secrets are given away here since parts of the hash are
+ * xored together before returned.
+ *
+ * Honor the request from the caller to only return good data, any data,
+ * etc.
+ */
+
+void
+isc_entropy_putdata(isc_entropy_t *ent, void *data, unsigned int length,
+ isc_uint32_t entropy);
+/*!<
+ * \brief Add "length" bytes in "data" to the entropy pool, incrementing the pool's
+ * entropy count by "entropy."
+ *
+ * These bytes will prime the pseudorandom portion even no entropy is actually
+ * added.
+ */
+
+void
+isc_entropy_stats(isc_entropy_t *ent, FILE *out);
+/*!<
+ * \brief Dump some (trivial) stats to the stdio stream "out".
+ */
+
+isc_result_t
+isc_entropy_usebestsource(isc_entropy_t *ectx, isc_entropysource_t **source,
+ const char *randomfile, int use_keyboard);
+/*!<
+ * \brief Use whatever source of entropy is best.
+ *
+ * Notes:
+ *\li If "randomfile" is not NULL, open it with
+ * isc_entropy_createfilesource().
+ *
+ *\li If "randomfile" is NULL and the system's random device was detected
+ * when the program was configured and built, open that device with
+ * isc_entropy_createfilesource().
+ *
+ *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDYES, then always open
+ * the keyboard as an entropy source (possibly in addition to
+ * "randomfile" or the random device).
+ *
+ *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDMAYBE, open the keyboard only
+ * if opening the random file/device fails. A message will be
+ * printed describing the need for keyboard input.
+ *
+ *\li If "use_keyboard" is #ISC_ENTROPY_KEYBOARDNO, the keyboard will
+ * never be opened.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS if at least one source of entropy could be started.
+ *
+ *\li #ISC_R_NOENTROPY if use_keyboard is #ISC_ENTROPY_KEYBOARDNO and
+ * there is no random device pathname compiled into the program.
+ *
+ *\li A return code from isc_entropy_createfilesource() or
+ * isc_entropy_createcallbacksource().
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_ENTROPY_H */
diff --git a/lib/isc/include/isc/error.h b/lib/isc/include/isc/error.h
new file mode 100644
index 000000000000..3320ae954b23
--- /dev/null
+++ b/lib/isc/include/isc/error.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-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 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.14.18.2 2005/04/29 00:16:54 marka Exp $ */
+
+#ifndef ISC_ERROR_H
+#define ISC_ERROR_H 1
+
+/*! \file */
+
+#include <stdarg.h>
+
+#include <isc/formatcheck.h>
+#include <isc/lang.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 */
+void
+isc_error_fatal(const char *, int, const char *, ...)
+ ISC_FORMAT_PRINTF(3, 4);
+
+/*% 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/lib/isc/include/isc/event.h b/lib/isc/include/isc/event.h
new file mode 100644
index 000000000000..f1b1d61118d9
--- /dev/null
+++ b/lib/isc/include/isc/event.h
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 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 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.27.18.3 2005/04/29 00:16:54 marka Exp $ */
+
+#ifndef ISC_EVENT_H
+#define ISC_EVENT_H 1
+
+/*! \file */
+
+#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/lib/isc/include/isc/eventclass.h b/lib/isc/include/isc/eventclass.h
new file mode 100644
index 000000000000..71de71562770
--- /dev/null
+++ b/lib/isc/include/isc/eventclass.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-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 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.14.18.2 2005/04/29 00:16:54 marka 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/lib/isc/include/isc/file.h b/lib/isc/include/isc/file.h
new file mode 100644
index 000000000000..16b007572581
--- /dev/null
+++ b/lib/isc/include/isc/file.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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.h,v 1.27.18.2 2005/04/29 00:16:54 marka Exp $ */
+
+#ifndef ISC_FILE_H
+#define ISC_FILE_H 1
+
+/*! \file */
+
+#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 *time);
+
+isc_result_t
+isc_file_getmodtime(const char *file, isc_time_t *time);
+/*!<
+ * \brief Get the time of last modication 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);
+/*!<
+ * \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_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_LANG_ENDDECLS
+
+#endif /* ISC_FILE_H */
diff --git a/lib/isc/include/isc/formatcheck.h b/lib/isc/include/isc/formatcheck.h
new file mode 100644
index 000000000000..93c62327ed74
--- /dev/null
+++ b/lib/isc/include/isc/formatcheck.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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.7.18.2 2005/04/29 00:16:54 marka Exp $ */
+
+#ifndef ISC_FORMATCHECK_H
+#define ISC_FORMATCHECK_H 1
+
+/*! \file */
+
+/*%
+ * 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/lib/isc/include/isc/fsaccess.h b/lib/isc/include/isc/fsaccess.h
new file mode 100644
index 000000000000..70c4d7c4db78
--- /dev/null
+++ b/lib/isc/include/isc/fsaccess.h
@@ -0,0 +1,177 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: fsaccess.h,v 1.8.18.2 2005/04/29 00:16:55 marka Exp $ */
+
+#ifndef ISC_FSACCESS_H
+#define ISC_FSACCESS_H 1
+
+/*! \file
+ * \brief The ISC filesystem access module encapsulates the setting of file
+ * and directory access permissions into one API that is meant to be
+ * portable to multiple operating systems.
+ *
+ * The two primary operating system flavors that are initially accomodated are
+ * POSIX and Windows NT 4.0 and later. The Windows NT access model is
+ * considerable more flexible than POSIX's model (as much as I am loathe to
+ * admit it), and so the ISC API has a higher degree of complexity than would
+ * be needed to simply address POSIX's needs.
+ *
+ * The full breadth of NT's flexibility is not available either, for the
+ * present time. Much of it is to provide compatibility with what Unix
+ * programmers are expecting. This is also due to not yet really needing all
+ * of the functionality of an NT system (or, for that matter, a POSIX system)
+ * in BIND9, and so resolving how to handle the various incompatibilities has
+ * been a purely theoretical exercise with no operational experience to
+ * indicate how flawed the thinking may be.
+ *
+ * Some of the more notable dumbing down of NT for this API includes:
+ *
+ *\li Each of FILE_READ_DATA and FILE_READ_EA are set with #ISC_FSACCESS_READ.
+ *
+ * \li All of FILE_WRITE_DATA, FILE_WRITE_EA and FILE_APPEND_DATA are
+ * set with #ISC_FSACCESS_WRITE. FILE_WRITE_ATTRIBUTES is not set
+ * so as to be consistent with Unix, where only the owner of the file
+ * or the superuser can change the attributes/mode of a file.
+ *
+ * \li Both of FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY are set with
+ * #ISC_FSACCESS_CREATECHILD. This is similar to setting the WRITE
+ * permission on a Unix directory.
+ *
+ * \li SYNCHRONIZE is always set for files and directories, unless someone
+ * can give me a reason why this is a bad idea.
+ *
+ * \li READ_CONTROL and FILE_READ_ATTRIBUTES are always set; this is
+ * consistent with Unix, where any file or directory can be stat()'d
+ * unless the directory path disallows complete access somewhere along
+ * the way.
+ *
+ * \li WRITE_DAC is only set for the owner. This too is consistent with
+ * Unix, and is tighter security than allowing anyone else to be
+ * able to set permissions.
+ *
+ * \li DELETE is only set for the owner. On Unix the ability to delete
+ * a file is controlled by the directory permissions, but it isn't
+ * currently clear to me what happens on NT if the directory has
+ * FILE_DELETE_CHILD set but a file within it does not have DELETE
+ * set. Always setting DELETE on the file/directory for the owner
+ * gives maximum flexibility to the owner without exposing the
+ * file to deletion by others.
+ *
+ * \li WRITE_OWNER is never set. This too is consistent with Unix,
+ * and is also tighter security than allowing anyone to change the
+ * ownership of the file apart from the superu..ahem, Administrator.
+ *
+ * \li Inheritance is set to NO_INHERITANCE.
+ *
+ * Unix's dumbing down includes:
+ *
+ * \li The sticky bit cannot be set.
+ *
+ * \li setuid and setgid cannot be set.
+ *
+ * \li Only regular files and directories can be set.
+ *
+ * The rest of this comment discusses a few of the incompatibilities
+ * between the two systems that need more thought if this API is to
+ * be extended to accomodate them.
+ *
+ * The Windows standard access right "DELETE" doesn't have a direct
+ * equivalent in the Unix world, so it isn't clear what should be done
+ * with it.
+ *
+ * The Unix sticky bit is not supported. While NT does have a concept
+ * of allowing users to create files in a directory but not delete or
+ * rename them, it does not have a concept of allowing them to be deleted
+ * if they are owned by the user trying to delete/rename. While it is
+ * probable that something could be cobbled together in NT 5 with inheritence,
+ * it can't really be done in NT 4 as a single property that you could
+ * set on a directory. You'd need to coordinate something with file creation
+ * so that every file created had DELETE set for the owner but noone else.
+ *
+ * On Unix systems, setting #ISC_FSACCESS_LISTDIRECTORY sets READ.
+ * ... setting either of #ISC_FSACCESS_(CREATE|DELETE)CHILD sets WRITE.
+ * ... setting #ISC_FSACCESS_ACCESSCHILD sets EXECUTE.
+ *
+ * On NT systems, setting #ISC_FSACCESS_LISTDIRECTORY sets FILE_LIST_DIRECTORY.
+ * ... setting ISC_FSACCESS_(CREATE|DELETE)CHILD sets
+ * FILE_(CREATE|DELETE)_CHILD independently.
+ * ... setting #ISC_FSACCESS_ACCESSCHILD sets FILE_TRAVERSE.
+ *
+ * Unresolved: XXXDCL
+ * \li What NT access right controls the ability to rename a file?
+ * \li How does DELETE work? If a directory has FILE_DELETE_CHILD but a
+ * file or directory within it does not have DELETE, is that file
+ * or directory deletable?
+ * \li To implement isc_fsaccess_get(), mapping an existing Unix permission
+ * mode_t back to an isc_fsaccess_t is pretty trivial; however, mapping
+ * an NT DACL could be impossible to do in a responsible way.
+ * \li Similarly, trying to implement the functionality of being able to
+ * say "add group writability to whatever permissions already exist"
+ * could be tricky on NT because of the order-of-entry issue combined
+ * with possibly having one or more matching ACEs already explicitly
+ * granting or denying access. Because this functionality is
+ * not yet needed by the ISC, no code has been written to try to
+ * solve this problem.
+ */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*
+ * Trustees.
+ */
+#define ISC_FSACCESS_OWNER 0x1 /*%< User account. */
+#define ISC_FSACCESS_GROUP 0x2 /*%< Primary group owner. */
+#define ISC_FSACCESS_OTHER 0x4 /*%< Not the owner or the group owner. */
+#define ISC_FSACCESS_WORLD 0x7 /*%< User, Group, Other. */
+
+/*
+ * Types of permission.
+ */
+#define ISC_FSACCESS_READ 0x00000001 /*%< File only. */
+#define ISC_FSACCESS_WRITE 0x00000002 /*%< File only. */
+#define ISC_FSACCESS_EXECUTE 0x00000004 /*%< File only. */
+#define ISC_FSACCESS_CREATECHILD 0x00000008 /*%< Dir only. */
+#define ISC_FSACCESS_DELETECHILD 0x00000010 /*%< Dir only. */
+#define ISC_FSACCESS_LISTDIRECTORY 0x00000020 /*%< Dir only. */
+#define ISC_FSACCESS_ACCESSCHILD 0x00000040 /*%< Dir only. */
+
+/*%
+ * Adding any permission bits beyond 0x200 would mean typedef'ing
+ * isc_fsaccess_t as isc_uint64_t, and redefining this value to
+ * reflect the new range of permission types, Probably to 21 for
+ * maximum flexibility. The number of bits has to accomodate all of
+ * the permission types, and three full sets of them have to fit
+ * within an isc_fsaccess_t.
+ */
+#define ISC__FSACCESS_PERMISSIONBITS 10
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_fsaccess_add(int trustee, int permission, isc_fsaccess_t *access);
+
+void
+isc_fsaccess_remove(int trustee, int permission, isc_fsaccess_t *access);
+
+isc_result_t
+isc_fsaccess_set(const char *path, isc_fsaccess_t access);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_FSACCESS_H */
diff --git a/lib/isc/include/isc/hash.h b/lib/isc/include/isc/hash.h
new file mode 100644
index 000000000000..cd29cdf865e3
--- /dev/null
+++ b/lib/isc/include/isc/hash.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2003 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 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.4.18.2 2005/04/29 00:16:55 marka Exp $ */
+
+#ifndef ISC_HASH_H
+#define ISC_HASH_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ *
+ * \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.
+ *
+ * Altough 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/lib/isc/include/isc/heap.h b/lib/isc/include/isc/heap.h
new file mode 100644
index 000000000000..d54a8d5b76cc
--- /dev/null
+++ b/lib/isc/include/isc/heap.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-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 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: heap.h,v 1.17.18.3 2006/04/17 18:27:33 explorer Exp $ */
+
+#ifndef ISC_HEAP_H
+#define ISC_HEAP_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*%
+ * The comparision function returns ISC_TRUE if the first argument has
+ * higher priority than the second argument, and ISC_FALSE otherwise.
+ */
+typedef isc_boolean_t (*isc_heapcompare_t)(void *, void *);
+
+/*%
+ * The index function allows the client of the heap to receive a callback
+ * when an item's index number changes. This allows it to maintain
+ * sync with its external state, but still delete itself, since deletions
+ * from the heap require the index be provided.
+ */
+typedef void (*isc_heapindex_t)(void *, unsigned int);
+
+/*%
+ * The heapaction function is used when iterating over the heap.
+ *
+ * NOTE: The heap structure CANNOT BE MODIFIED during the call to
+ * isc_heap_foreach().
+ */
+typedef void (*isc_heapaction_t)(void *, void *);
+
+typedef struct isc_heap isc_heap_t;
+
+isc_result_t
+isc_heap_create(isc_mem_t *mctx, isc_heapcompare_t compare,
+ isc_heapindex_t index, unsigned int size_increment,
+ isc_heap_t **heapp);
+/*!<
+ * \brief Create a new heap. The heap is implemented using a space-efficient
+ * storage method. When the heap elements are deleted space is not freed
+ * but will be reused when new elements are inserted.
+ *
+ * Requires:
+ *\li "mctx" is valid.
+ *\li "compare" is a function which takes two void * arguments and
+ * returns ISC_TRUE if the first argument has a higher priority than
+ * the second, and ISC_FALSE otherwise.
+ *\li "index" is a function which takes a void *, and an unsigned int
+ * argument. This function will be called whenever an element's
+ * index value changes, so it may continue to delete itself from the
+ * heap. This option may be NULL if this functionality is unneeded.
+ *\li "size_increment" is a hint about how large the heap should grow
+ * when resizing is needed. If this is 0, a default size will be
+ * used, which is currently 1024, allowing space for an additional 1024
+ * heap elements to be inserted before adding more space.
+ *\li "heapp" is not NULL, and "*heap" is NULL.
+ *
+ * Returns:
+ *\li ISC_R_SUCCESS - success
+ *\li ISC_R_NOMEMORY - insufficient memory
+ */
+
+void
+isc_heap_destroy(isc_heap_t **heapp);
+/*!<
+ * \brief Destroys a heap.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ */
+
+isc_result_t
+isc_heap_insert(isc_heap_t *heap, void *elt);
+/*!<
+ * \brief Inserts a new element into a heap.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ */
+
+void
+isc_heap_delete(isc_heap_t *heap, unsigned int index);
+/*!<
+ * \brief Deletes an element from a heap, by element index.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "index" is a valid element index, as provided by the "index" callback
+ * provided during heap creation.
+ */
+
+void
+isc_heap_increased(isc_heap_t *heap, unsigned int index);
+/*!<
+ * \brief Indicates to the heap that an element's priority has increased.
+ * This function MUST be called whenever an element has increased in priority.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "index" is a valid element index, as provided by the "index" callback
+ * provided during heap creation.
+ */
+
+void
+isc_heap_decreased(isc_heap_t *heap, unsigned int index);
+/*!<
+ * \brief Indicates to the heap that an element's priority has decreased.
+ * This function MUST be called whenever an element has decreased in priority.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "index" is a valid element index, as provided by the "index" callback
+ * provided during heap creation.
+ */
+
+void *
+isc_heap_element(isc_heap_t *heap, unsigned int index);
+/*!<
+ * \brief Returns the element for a specific element index.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "index" is a valid element index, as provided by the "index" callback
+ * provided during heap creation.
+ *
+ * Returns:
+ *\li A pointer to the element for the element index.
+ */
+
+void
+isc_heap_foreach(isc_heap_t *heap, isc_heapaction_t action, void *uap);
+/*!<
+ * \brief Iterate over the heap, calling an action for each element. The
+ * order of iteration is not sorted.
+ *
+ * Requires:
+ *\li "heapp" is not NULL and "*heap" points to a valid isc_heap_t.
+ *\li "action" is not NULL, and is a function which takes two arguments.
+ * The first is a void *, representing the element, and the second is
+ * "uap" as provided to isc_heap_foreach.
+ *\li "uap" is a caller-provided argument, and may be NULL.
+ *
+ * Note:
+ *\li The heap structure CANNOT be modified during this iteration. The only
+ * safe function to call while iterating the heap is isc_heap_element().
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HEAP_H */
diff --git a/lib/isc/include/isc/hex.h b/lib/isc/include/isc/hex.h
new file mode 100644
index 000000000000..9124a9b3c200
--- /dev/null
+++ b/lib/isc/include/isc/hex.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: hex.h,v 1.5.18.2 2005/04/29 00:16:55 marka Exp $ */
+
+#ifndef ISC_HEX_H
+#define ISC_HEX_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_hex_totext(isc_region_t *source, int wordlength,
+ const char *wordbreak, isc_buffer_t *target);
+/*!<
+ * \brief Convert data into hex encoded text.
+ *
+ * Notes:
+ *\li The hex encoded text in 'target' will be divided into
+ * words of at most 'wordlength' characters, separated by
+ * the 'wordbreak' string. No parentheses will surround
+ * the text.
+ *
+ * Requires:
+ *\li 'source' is a region containing binary data
+ *\li 'target' is a text buffer containing available space
+ *\li 'wordbreak' points to a null-terminated string of
+ * zero or more whitespace characters
+ *
+ * Ensures:
+ *\li target will contain the hex encoded version of the data
+ * in source. The 'used' pointer in target will be advanced as
+ * necessary.
+ */
+
+isc_result_t
+isc_hex_decodestring(char *cstr, isc_buffer_t *target);
+/*!<
+ * \brief Decode a null-terminated hex string.
+ *
+ * Requires:
+ *\li 'cstr' is non-null.
+ *\li 'target' is a valid buffer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS -- the entire decoded representation of 'cstring'
+ * fit in 'target'.
+ *\li #ISC_R_BADHEX -- 'cstr' is not a valid hex encoding.
+ *
+ * Other error returns are any possible error code from:
+ * isc_lex_create(),
+ * isc_lex_openbuffer(),
+ * isc_hex_tobuffer().
+ */
+
+isc_result_t
+isc_hex_tobuffer(isc_lex_t *lexer, isc_buffer_t *target, int length);
+/*!<
+ * \brief Convert hex encoded text from a lexer context into data.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer context
+ *\li 'target' is a buffer containing binary data
+ *\li 'length' is an integer
+ *
+ * Ensures:
+ *\li target will contain the data represented by the hex encoded
+ * string parsed by the lexer. No more than length bytes will be read,
+ * if length is positive. The 'used' pointer in target will be
+ * advanced as necessary.
+ */
+
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HEX_H */
diff --git a/lib/isc/include/isc/hmacmd5.h b/lib/isc/include/isc/hmacmd5.h
new file mode 100644
index 000000000000..5c05675e42cd
--- /dev/null
+++ b/lib/isc/include/isc/hmacmd5.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: hmacmd5.h,v 1.5.18.4 2006/01/27 23:57:45 marka Exp $ */
+
+/*! \file
+ * \brief This is the header file for the HMAC-MD5 keyed hash algorithm
+ * described in RFC2104.
+ */
+
+#ifndef ISC_HMACMD5_H
+#define ISC_HMACMD5_H 1
+
+#include <isc/lang.h>
+#include <isc/md5.h>
+#include <isc/types.h>
+
+#define ISC_HMACMD5_KEYLENGTH 64
+
+typedef struct {
+ isc_md5_t md5ctx;
+ unsigned char key[ISC_HMACMD5_KEYLENGTH];
+} isc_hmacmd5_t;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_hmacmd5_init(isc_hmacmd5_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacmd5_invalidate(isc_hmacmd5_t *ctx);
+
+void
+isc_hmacmd5_update(isc_hmacmd5_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacmd5_sign(isc_hmacmd5_t *ctx, unsigned char *digest);
+
+isc_boolean_t
+isc_hmacmd5_verify(isc_hmacmd5_t *ctx, unsigned char *digest);
+
+isc_boolean_t
+isc_hmacmd5_verify2(isc_hmacmd5_t *ctx, unsigned char *digest, size_t len);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HMACMD5_H */
diff --git a/lib/isc/include/isc/hmacsha.h b/lib/isc/include/isc/hmacsha.h
new file mode 100644
index 000000000000..fce645c56ee5
--- /dev/null
+++ b/lib/isc/include/isc/hmacsha.h
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2005, 2006 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * 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 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: hmacsha.h,v 1.2.2.3 2006/08/16 03:18:14 marka Exp $ */
+
+/*
+ * This is the header file for the HMAC-SHA1, HMAC-SHA224, HMAC-SHA256,
+ * HMAC-SHA334 and HMAC-SHA512 hash algorithm described in RFC 2104.
+ */
+
+#ifndef ISC_HMACSHA_H
+#define ISC_HMACSHA_H 1
+
+#include <isc/lang.h>
+#include <isc/sha1.h>
+#include <isc/sha2.h>
+#include <isc/types.h>
+
+#define ISC_HMACSHA1_KEYLENGTH ISC_SHA1_BLOCK_LENGTH
+#define ISC_HMACSHA224_KEYLENGTH ISC_SHA224_BLOCK_LENGTH
+#define ISC_HMACSHA256_KEYLENGTH ISC_SHA256_BLOCK_LENGTH
+#define ISC_HMACSHA384_KEYLENGTH ISC_SHA384_BLOCK_LENGTH
+#define ISC_HMACSHA512_KEYLENGTH ISC_SHA512_BLOCK_LENGTH
+
+typedef struct {
+ isc_sha1_t sha1ctx;
+ unsigned char key[ISC_HMACSHA1_KEYLENGTH];
+} isc_hmacsha1_t;
+
+typedef struct {
+ isc_sha224_t sha224ctx;
+ unsigned char key[ISC_HMACSHA224_KEYLENGTH];
+} isc_hmacsha224_t;
+
+typedef struct {
+ isc_sha256_t sha256ctx;
+ unsigned char key[ISC_HMACSHA256_KEYLENGTH];
+} isc_hmacsha256_t;
+
+typedef struct {
+ isc_sha384_t sha384ctx;
+ unsigned char key[ISC_HMACSHA384_KEYLENGTH];
+} isc_hmacsha384_t;
+
+typedef struct {
+ isc_sha512_t sha512ctx;
+ unsigned char key[ISC_HMACSHA512_KEYLENGTH];
+} isc_hmacsha512_t;
+
+ISC_LANG_BEGINDECLS
+
+void
+isc_hmacsha1_init(isc_hmacsha1_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha1_invalidate(isc_hmacsha1_t *ctx);
+
+void
+isc_hmacsha1_update(isc_hmacsha1_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha1_sign(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha1_verify(isc_hmacsha1_t *ctx, unsigned char *digest, size_t len);
+
+
+void
+isc_hmacsha224_init(isc_hmacsha224_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha224_invalidate(isc_hmacsha224_t *ctx);
+
+void
+isc_hmacsha224_update(isc_hmacsha224_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha224_sign(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha224_verify(isc_hmacsha224_t *ctx, unsigned char *digest, size_t len);
+
+
+void
+isc_hmacsha256_init(isc_hmacsha256_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha256_invalidate(isc_hmacsha256_t *ctx);
+
+void
+isc_hmacsha256_update(isc_hmacsha256_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha256_sign(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha256_verify(isc_hmacsha256_t *ctx, unsigned char *digest, size_t len);
+
+
+void
+isc_hmacsha384_init(isc_hmacsha384_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha384_invalidate(isc_hmacsha384_t *ctx);
+
+void
+isc_hmacsha384_update(isc_hmacsha384_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha384_sign(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha384_verify(isc_hmacsha384_t *ctx, unsigned char *digest, size_t len);
+
+
+void
+isc_hmacsha512_init(isc_hmacsha512_t *ctx, const unsigned char *key,
+ unsigned int len);
+
+void
+isc_hmacsha512_invalidate(isc_hmacsha512_t *ctx);
+
+void
+isc_hmacsha512_update(isc_hmacsha512_t *ctx, const unsigned char *buf,
+ unsigned int len);
+
+void
+isc_hmacsha512_sign(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len);
+
+isc_boolean_t
+isc_hmacsha512_verify(isc_hmacsha512_t *ctx, unsigned char *digest, size_t len);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_HMACSHA_H */
diff --git a/lib/isc/include/isc/interfaceiter.h b/lib/isc/include/isc/interfaceiter.h
new file mode 100644
index 000000000000..12ec188dee01
--- /dev/null
+++ b/lib/isc/include/isc/interfaceiter.h
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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.11.18.2 2005/04/29 00:16:55 marka Exp $ */
+
+#ifndef ISC_INTERFACEITER_H
+#define ISC_INTERFACEITER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \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 dstaddress; /*%< Destination address (point-to-point only). */
+ isc_uint32_t flags; /*%< Flags; see INTERFACE flags. */
+};
+
+/*@{*/
+/*! Interface flags. */
+
+#define INTERFACE_F_UP 0x00000001U
+#define INTERFACE_F_POINTTOPOINT 0x00000002U
+#define INTERFACE_F_LOOPBACK 0x00000004U
+/*@}*/
+
+/***
+ *** 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/lib/isc/include/isc/ipv6.h b/lib/isc/include/isc/ipv6.h
new file mode 100644
index 000000000000..7c88f2be86fb
--- /dev/null
+++ b/lib/isc/include/isc/ipv6.h
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 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 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: ipv6.h,v 1.20.18.2 2005/04/29 00:16:56 marka Exp $ */
+
+#ifndef ISC_IPV6_H
+#define ISC_IPV6_H 1
+
+/*!
+ * 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
+ *****/
+
+/*! \file isc/ipv6.h
+ * \brief IPv6 definitions for systems which do not support IPv6.
+ *
+ * \li MP:
+ * No impact.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * N/A.
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * RFC2553.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/int.h>
+#include <isc/platform.h>
+
+/***
+ *** Types.
+ ***/
+
+struct in6_addr {
+ union {
+ isc_uint8_t _S6_u8[16];
+ isc_uint16_t _S6_u16[8];
+ isc_uint32_t _S6_u32[4];
+ } _S6_un;
+};
+#define s6_addr _S6_un._S6_u8
+#define s6_addr8 _S6_un._S6_u8
+#define s6_addr16 _S6_un._S6_u16
+#define s6_addr32 _S6_un._S6_u32
+
+#define IN6ADDR_ANY_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }}}
+#define IN6ADDR_LOOPBACK_INIT {{{ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }}}
+
+LIBISC_EXTERNAL_DATA extern const struct in6_addr in6addr_any;
+LIBISC_EXTERNAL_DATA extern const struct in6_addr in6addr_loopback;
+
+struct sockaddr_in6 {
+#ifdef ISC_PLATFORM_HAVESALEN
+ isc_uint8_t sin6_len;
+ isc_uint8_t sin6_family;
+#else
+ isc_uint16_t sin6_family;
+#endif
+ isc_uint16_t sin6_port;
+ isc_uint32_t sin6_flowinfo;
+ struct in6_addr sin6_addr;
+ isc_uint32_t sin6_scope_id;
+};
+
+#ifdef ISC_PLATFORM_HAVESALEN
+#define SIN6_LEN 1
+#endif
+
+/*%
+ * Unspecified
+ */
+#define IN6_IS_ADDR_UNSPECIFIED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] == 0))
+
+/*%
+ * Loopback
+ */
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] == htonl(1)))
+
+/*%
+ * IPv4 compatible
+ */
+#define IN6_IS_ADDR_V4COMPAT(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == 0) && \
+ ((a)->s6_addr32[3] != 0) && \
+ ((a)->s6_addr32[3] != htonl(1)))
+
+/*%
+ * Mapped
+ */
+#define IN6_IS_ADDR_V4MAPPED(a) \
+ (((a)->s6_addr32[0] == 0) && \
+ ((a)->s6_addr32[1] == 0) && \
+ ((a)->s6_addr32[2] == htonl(0x0000ffff)))
+
+/*%
+ * Multicast
+ */
+#define IN6_IS_ADDR_MULTICAST(a) \
+ ((a)->s6_addr8[0] == 0xffU)
+
+/*%
+ * Unicast link / site local.
+ */
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+
+#endif /* ISC_IPV6_H */
diff --git a/lib/isc/include/isc/lang.h b/lib/isc/include/isc/lang.h
new file mode 100644
index 000000000000..abe16f5a11c8
--- /dev/null
+++ b/lib/isc/include/isc/lang.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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.7.18.2 2005/04/29 00:16:56 marka Exp $ */
+
+#ifndef ISC_LANG_H
+#define ISC_LANG_H 1
+
+/*! \file */
+
+#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/lib/isc/include/isc/lex.h b/lib/isc/include/isc/lex.h
new file mode 100644
index 000000000000..8c6624a4988d
--- /dev/null
+++ b/lib/isc/include/isc/lex.h
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 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 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: lex.h,v 1.30.18.3 2005/06/04 00:39:05 marka Exp $ */
+
+#ifndef ISC_LEX_H
+#define ISC_LEX_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/lex.h
+ * \brief The "lex" module provides a lightweight tokenizer. It can operate
+ * on files or buffers, and can handle "include". It is designed for
+ * parsing of DNS master files and the BIND configuration file, but
+ * should be general enough to tokenize other things, e.g. HTTP.
+ *
+ * \li MP:
+ * No synchronization is provided. Clients must ensure exclusive
+ * access.
+ *
+ * \li Reliability:
+ * No anticipated impact.
+ *
+ * \li Resources:
+ * TBS
+ *
+ * \li Security:
+ * No anticipated impact.
+ *
+ * \li Standards:
+ * None.
+ */
+
+/***
+ *** Imports
+ ***/
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/region.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/***
+ *** Options
+ ***/
+
+/*@{*/
+/*!
+ * Various options for isc_lex_gettoken().
+ */
+
+#define ISC_LEXOPT_EOL 0x01 /*%< Want end-of-line token. */
+#define ISC_LEXOPT_EOF 0x02 /*%< Want end-of-file token. */
+#define ISC_LEXOPT_INITIALWS 0x04 /*%< Want initial whitespace. */
+#define ISC_LEXOPT_NUMBER 0x08 /*%< Recognize numbers. */
+#define ISC_LEXOPT_QSTRING 0x10 /*%< Recognize qstrings. */
+/*@}*/
+
+/*@{*/
+/*!
+ * The ISC_LEXOPT_DNSMULTILINE option handles the processing of '(' and ')' in
+ * the DNS master file format. If this option is set, then the
+ * ISC_LEXOPT_INITIALWS and ISC_LEXOPT_EOL options will be ignored when
+ * the paren count is > 0. To use this option, '(' and ')' must be special
+ * characters.
+ */
+#define ISC_LEXOPT_DNSMULTILINE 0x20 /*%< Handle '(' and ')'. */
+#define ISC_LEXOPT_NOMORE 0x40 /*%< Want "no more" token. */
+
+#define ISC_LEXOPT_CNUMBER 0x80 /*%< Regognize octal and hex. */
+#define ISC_LEXOPT_ESCAPE 0x100 /*%< Recognize escapes. */
+#define ISC_LEXOPT_QSTRINGMULTILINE 0x200 /*%< Allow multiline "" strings */
+#define ISC_LEXOPT_OCTAL 0x400 /*%< Expect a octal number. */
+/*@}*/
+/*@{*/
+/*!
+ * Various commenting styles, which may be changed at any time with
+ * isc_lex_setcomments().
+ */
+
+#define ISC_LEXCOMMENT_C 0x01
+#define ISC_LEXCOMMENT_CPLUSPLUS 0x02
+#define ISC_LEXCOMMENT_SHELL 0x04
+#define ISC_LEXCOMMENT_DNSMASTERFILE 0x08
+/*@}*/
+
+/***
+ *** Types
+ ***/
+
+/*! Lex */
+
+typedef char isc_lexspecials_t[256];
+
+/* Tokens */
+
+typedef enum {
+ isc_tokentype_unknown = 0,
+ isc_tokentype_string = 1,
+ isc_tokentype_number = 2,
+ isc_tokentype_qstring = 3,
+ isc_tokentype_eol = 4,
+ isc_tokentype_eof = 5,
+ isc_tokentype_initialws = 6,
+ isc_tokentype_special = 7,
+ isc_tokentype_nomore = 8
+} isc_tokentype_t;
+
+typedef union {
+ char as_char;
+ unsigned long as_ulong;
+ isc_region_t as_region;
+ isc_textregion_t as_textregion;
+ void * as_pointer;
+} isc_tokenvalue_t;
+
+typedef struct isc_token {
+ isc_tokentype_t type;
+ isc_tokenvalue_t value;
+} isc_token_t;
+
+/***
+ *** Functions
+ ***/
+
+isc_result_t
+isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp);
+/*%<
+ * Create a lexer.
+ *
+ * 'max_token' is a hint of the number of bytes in the largest token.
+ *
+ * Requires:
+ *\li '*lexp' is a valid lexer.
+ *
+ *\li max_token > 0.
+ *
+ * Ensures:
+ *\li On success, *lexp is attached to the newly created lexer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ */
+
+void
+isc_lex_destroy(isc_lex_t **lexp);
+/*%<
+ * Destroy the lexer.
+ *
+ * Requires:
+ *\li '*lexp' is a valid lexer.
+ *
+ * Ensures:
+ *\li *lexp == NULL
+ */
+
+unsigned int
+isc_lex_getcomments(isc_lex_t *lex);
+/*%<
+ * Return the current lexer commenting styles.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ * Returns:
+ *\li The commenting sytles which are currently allowed.
+ */
+
+void
+isc_lex_setcomments(isc_lex_t *lex, unsigned int comments);
+/*%<
+ * Set allowed lexer commenting styles.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'comments' has meaningful values.
+ */
+
+void
+isc_lex_getspecials(isc_lex_t *lex, isc_lexspecials_t specials);
+/*%<
+ * Put the current list of specials into 'specials'.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ */
+
+void
+isc_lex_setspecials(isc_lex_t *lex, isc_lexspecials_t specials);
+/*!<
+ * The characters in 'specials' are returned as tokens. Along with
+ * whitespace, they delimit strings and numbers.
+ *
+ * Note:
+ *\li Comment processing takes precedence over special character
+ * recognition.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ */
+
+isc_result_t
+isc_lex_openfile(isc_lex_t *lex, const char *filename);
+/*%<
+ * Open 'filename' and make it the current input source for 'lex'.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li filename is a valid C string.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY Out of memory
+ *\li #ISC_R_NOTFOUND File not found
+ *\li #ISC_R_NOPERM No permission to open file
+ *\li #ISC_R_FAILURE Couldn't open file, not sure why
+ *\li #ISC_R_UNEXPECTED
+ */
+
+isc_result_t
+isc_lex_openstream(isc_lex_t *lex, FILE *stream);
+/*%<
+ * Make 'stream' the current input source for 'lex'.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'stream' is a valid C stream.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY Out of memory
+ */
+
+isc_result_t
+isc_lex_openbuffer(isc_lex_t *lex, isc_buffer_t *buffer);
+/*%<
+ * Make 'buffer' the current input source for 'lex'.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'buffer' is a valid buffer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY Out of memory
+ */
+
+isc_result_t
+isc_lex_close(isc_lex_t *lex);
+/*%<
+ * Close the most recently opened object (i.e. file or buffer).
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMORE No more input sources
+ */
+
+isc_result_t
+isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp);
+/*%<
+ * Get the next token.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'lex' has an input source.
+ *
+ *\li 'options' contains valid options.
+ *
+ *\li '*tokenp' is a valid pointer.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_UNEXPECTEDEND
+ *\li #ISC_R_NOMEMORY
+ *
+ * These two results are returned only if their corresponding lexer
+ * options are not set.
+ *
+ *\li #ISC_R_EOF End of input source
+ *\li #ISC_R_NOMORE No more input sources
+ */
+
+isc_result_t
+isc_lex_getmastertoken(isc_lex_t *lex, isc_token_t *token,
+ isc_tokentype_t expect, isc_boolean_t eol);
+/*%<
+ * Get the next token from a DNS master file type stream. This is a
+ * convenience function that sets appropriate options and handles quoted
+ * strings and end of line correctly for master files. It also ungets
+ * unexpected tokens.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'token' is a valid pointer
+ *
+ * Returns:
+ *
+ * \li any return code from isc_lex_gettoken().
+ */
+
+isc_result_t
+isc_lex_getoctaltoken(isc_lex_t *lex, isc_token_t *token, isc_boolean_t eol);
+/*%<
+ * Get the next token from a DNS master file type stream. This is a
+ * convenience function that sets appropriate options and handles end
+ * of line correctly for master files. It also ungets unexpected tokens.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'token' is a valid pointer
+ *
+ * Returns:
+ *
+ * \li any return code from isc_lex_gettoken().
+ */
+
+void
+isc_lex_ungettoken(isc_lex_t *lex, isc_token_t *tokenp);
+/*%<
+ * Unget the current token.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'lex' has an input source.
+ *
+ *\li 'tokenp' points to a valid token.
+ *
+ *\li There is no ungotten token already.
+ */
+
+void
+isc_lex_getlasttokentext(isc_lex_t *lex, isc_token_t *tokenp, isc_region_t *r);
+/*%<
+ * Returns a region containing the text of the last token returned.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ *\li 'lex' has an input source.
+ *
+ *\li 'tokenp' points to a valid token.
+ *
+ *\li A token has been gotten and not ungotten.
+ */
+
+char *
+isc_lex_getsourcename(isc_lex_t *lex);
+/*%<
+ * Return the input source name.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ * Returns:
+ * \li source name or NULL if no current source.
+ *\li result valid while current input source exists.
+ */
+
+
+unsigned long
+isc_lex_getsourceline(isc_lex_t *lex);
+/*%<
+ * Return the input source line number.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ * Returns:
+ *\li Current line number or 0 if no current source.
+ */
+
+isc_result_t
+isc_lex_setsourcename(isc_lex_t *lex, const char *name);
+/*%<
+ * Assigns a new name to the input source.
+ *
+ * Requires:
+ *
+ * \li 'lex' is a valid lexer.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_NOMEMORY
+ * \li #ISC_R_NOTFOUND - there are no sources.
+ */
+
+isc_boolean_t
+isc_lex_isfile(isc_lex_t *lex);
+/*%<
+ * Return whether the current input source is a file.
+ *
+ * Requires:
+ *\li 'lex' is a valid lexer.
+ *
+ * Returns:
+ * \li #ISC_TRUE if the current input is a file,
+ *\li #ISC_FALSE otherwise.
+ */
+
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LEX_H */
diff --git a/lib/isc/include/isc/lfsr.h b/lib/isc/include/isc/lfsr.h
new file mode 100644
index 000000000000..0c2e845b1e9c
--- /dev/null
+++ b/lib/isc/include/isc/lfsr.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: lfsr.h,v 1.11.18.2 2005/04/29 00:16:56 marka Exp $ */
+
+#ifndef ISC_LFSR_H
+#define ISC_LFSR_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+typedef struct isc_lfsr isc_lfsr_t;
+
+/*%
+ * This function is called when reseeding is needed. It is allowed to
+ * modify any state in the LFSR in any way it sees fit OTHER THAN "bits".
+ *
+ * It MUST set "count" to a new value or the lfsr will never reseed again.
+ *
+ * Also, a reseed will never occur in the middle of an extraction. This
+ * is purely an optimization, and is probably what one would want.
+ */
+typedef void (*isc_lfsrreseed_t)(isc_lfsr_t *, void *);
+
+/*%
+ * The members of this structure can be used by the application, but care
+ * needs to be taken to not change state once the lfsr is in operation.
+ */
+struct isc_lfsr {
+ isc_uint32_t state; /*%< previous state */
+ unsigned int bits; /*%< length */
+ isc_uint32_t tap; /*%< bit taps */
+ unsigned int count; /*%< reseed count (in BITS!) */
+ isc_lfsrreseed_t reseed; /*%< reseed function */
+ void *arg; /*%< reseed function argument */
+};
+
+ISC_LANG_BEGINDECLS
+
+
+void
+isc_lfsr_init(isc_lfsr_t *lfsr, isc_uint32_t state, unsigned int bits,
+ isc_uint32_t tap, unsigned int count,
+ isc_lfsrreseed_t reseed, void *arg);
+/*%<
+ * Initialize an LFSR.
+ *
+ * Note:
+ *
+ *\li Putting untrusted values into this function will cause the LFSR to
+ * generate (perhaps) non-maximal length sequences.
+ *
+ * Requires:
+ *
+ *\li lfsr != NULL
+ *
+ *\li 8 <= bits <= 32
+ *
+ *\li tap != 0
+ */
+
+void
+isc_lfsr_generate(isc_lfsr_t *lfsr, void *data, unsigned int count);
+/*%<
+ * Returns "count" bytes of data from the LFSR.
+ *
+ * Requires:
+ *
+ *\li lfsr be valid.
+ *
+ *\li data != NULL.
+ *
+ *\li count > 0.
+ */
+
+void
+isc_lfsr_skip(isc_lfsr_t *lfsr, unsigned int skip);
+/*%<
+ * Skip "skip" states.
+ *
+ * Requires:
+ *
+ *\li lfsr be valid.
+ */
+
+isc_uint32_t
+isc_lfsr_generate32(isc_lfsr_t *lfsr1, isc_lfsr_t *lfsr2);
+/*%<
+ * Given two LFSRs, use the current state from each to skip entries in the
+ * other. The next states are then xor'd together and returned.
+ *
+ * WARNING:
+ *
+ *\li This function is used only for very, very low security data, such
+ * as DNS message IDs where it is desired to have an unpredictable
+ * stream of bytes that are harder to predict than a simple flooding
+ * attack.
+ *
+ * Notes:
+ *
+ *\li Since the current state from each of the LFSRs is used to skip
+ * state in the other, it is important that no state be leaked
+ * from either LFSR.
+ *
+ * Requires:
+ *
+ *\li lfsr1 and lfsr2 be valid.
+ *
+ *\li 1 <= skipbits <= 31
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LFSR_H */
diff --git a/lib/isc/include/isc/lib.h b/lib/isc/include/isc/lib.h
new file mode 100644
index 000000000000..45c547c40a4f
--- /dev/null
+++ b/lib/isc/include/isc/lib.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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.8.18.2 2005/04/29 00:16:58 marka Exp $ */
+
+#ifndef ISC_LIB_H
+#define ISC_LIB_H 1
+
+/*! \file */
+
+#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.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_LIB_H */
diff --git a/lib/isc/include/isc/list.h b/lib/isc/include/isc/list.h
new file mode 100644
index 000000000000..2adc33f7edd4
--- /dev/null
+++ b/lib/isc/include/isc/list.h
@@ -0,0 +1,184 @@
+/*
+ * Copyright (C) 2004, 2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-2002 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 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: list.h,v 1.20.18.2 2006/06/06 00:11:41 marka Exp $ */
+
+#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_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/lib/isc/include/isc/log.h b/lib/isc/include/isc/log.h
new file mode 100644
index 000000000000..c3817758faee
--- /dev/null
+++ b/lib/isc/include/isc/log.h
@@ -0,0 +1,913 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 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 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.47.18.3 2005/04/29 00:16:58 marka Exp $ */
+
+#ifndef ISC_LOG_H
+#define ISC_LOG_H 1
+
+/*! \file */
+
+#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])
+
+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 Specifing 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 estabished 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 estabished 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 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 accomodate 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/lib/isc/include/isc/magic.h b/lib/isc/include/isc/magic.h
new file mode 100644
index 000000000000..045b54f9a013
--- /dev/null
+++ b/lib/isc/include/isc/magic.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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.12.18.2 2005/04/29 00:16:59 marka Exp $ */
+
+#ifndef ISC_MAGIC_H
+#define ISC_MAGIC_H 1
+
+/*! \file */
+
+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/lib/isc/include/isc/md5.h b/lib/isc/include/isc/md5.h
new file mode 100644
index 000000000000..3f9667e6ae78
--- /dev/null
+++ b/lib/isc/include/isc/md5.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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.9.18.4 2006/02/01 00:10:34 marka Exp $ */
+
+/*! \file
+ * \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/types.h>
+
+#define ISC_MD5_DIGESTLENGTH 16U
+
+typedef struct {
+ isc_uint32_t buf[4];
+ isc_uint32_t bytes[2];
+ isc_uint32_t in[16];
+} isc_md5_t;
+
+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/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h
new file mode 100644
index 000000000000..dc68bcb2a2d9
--- /dev/null
+++ b/lib/isc/include/isc/mem.h
@@ -0,0 +1,543 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1997-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 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: mem.h,v 1.59.18.9 2006/01/04 23:50:23 marka Exp $ */
+
+#ifndef ISC_MEM_H
+#define ISC_MEM_H 1
+
+/*! \file */
+
+#include <stdio.h>
+
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+#define ISC_MEM_LOWATER 0
+#define ISC_MEM_HIWATER 1
+typedef void (*isc_mem_water_t)(void *, int);
+
+typedef void * (*isc_memalloc_t)(void *, size_t);
+typedef void (*isc_memfree_t)(void *, void *);
+
+/*%
+ * Define ISC_MEM_DEBUG=1 to make all functions that free memory
+ * set the pointer being freed to NULL after being freed.
+ * This is the default; set ISC_MEM_DEBUG=0 to disable it.
+ */
+#ifndef ISC_MEM_DEBUG
+#define ISC_MEM_DEBUG 1
+#endif
+
+/*%
+ * Define ISC_MEM_TRACKLINES=1 to turn on detailed tracing of memory
+ * allocation and freeing by file and line number.
+ */
+#ifndef ISC_MEM_TRACKLINES
+#define ISC_MEM_TRACKLINES 1
+#endif
+
+/*%
+ * Define ISC_MEM_CHECKOVERRUN=1 to turn on checks for using memory outside
+ * the requested space. This will increase the size of each allocation.
+ */
+#ifndef ISC_MEM_CHECKOVERRUN
+#define ISC_MEM_CHECKOVERRUN 1
+#endif
+
+/*%
+ * Define ISC_MEM_FILL=1 to fill each block of memory returned to the system
+ * with the byte string '0xbe'. This helps track down uninitialized pointers
+ * and the like. On freeing memory, the space is filled with '0xde' for
+ * the same reasons.
+ */
+#ifndef ISC_MEM_FILL
+#define ISC_MEM_FILL 1
+#endif
+
+/*%
+ * Define ISC_MEMPOOL_NAMES=1 to make memory pools store a symbolic
+ * name so that the leaking pool can be more readily identified in
+ * case of a memory leak.
+ */
+#ifndef ISC_MEMPOOL_NAMES
+#define ISC_MEMPOOL_NAMES 1
+#endif
+
+LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging;
+/*@{*/
+#define ISC_MEM_DEBUGTRACE 0x00000001U
+#define ISC_MEM_DEBUGRECORD 0x00000002U
+#define ISC_MEM_DEBUGUSAGE 0x00000004U
+#define ISC_MEM_DEBUGSIZE 0x00000008U
+#define ISC_MEM_DEBUGCTX 0x00000010U
+#define ISC_MEM_DEBUGALL 0x0000001FU
+/*!<
+ * The variable isc_mem_debugging holds a set of flags for
+ * turning certain memory debugging options on or off at
+ * runtime. Its is intialized to the value ISC_MEM_DEGBUGGING,
+ * which is 0 by default but may be overridden at compile time.
+ * The following flags can be specified:
+ *
+ * \li #ISC_MEM_DEBUGTRACE
+ * Log each allocation and free to isc_lctx.
+ *
+ * \li #ISC_MEM_DEBUGRECORD
+ * Remember each allocation, and match them up on free.
+ * Crash if a free doesn't match an allocation.
+ *
+ * \li #ISC_MEM_DEBUGUSAGE
+ * If a hi_water mark is set, print the maximium inuse memory
+ * every time it is raised once it exceeds the hi_water mark.
+ *
+ * \li #ISC_MEM_DEBUGSIZE
+ * Check the size argument being passed to isc_mem_put() matches
+ * that passed to isc_mem_get().
+ *
+ * \li #ISC_MEM_DEBUGCTX
+ * Check the mctx argument being passed to isc_mem_put() matches
+ * that passed to isc_mem_get().
+ */
+/*@}*/
+
+#if ISC_MEM_TRACKLINES
+#define _ISC_MEM_FILELINE , __FILE__, __LINE__
+#define _ISC_MEM_FLARG , const char *, int
+#else
+#define _ISC_MEM_FILELINE
+#define _ISC_MEM_FLARG
+#endif
+
+/*!
+ * Define ISC_MEM_USE_INTERNAL_MALLOC=1 to use the internal malloc()
+ * implementation in preference to the system one. The internal malloc()
+ * is very space-efficient, and quite fast on uniprocessor systems. It
+ * performs poorly on multiprocessor machines.
+ * JT: we can overcome the performance issue on multiprocessor machines
+ * by carefully separating memory contexts.
+ */
+
+#ifndef ISC_MEM_USE_INTERNAL_MALLOC
+#define ISC_MEM_USE_INTERNAL_MALLOC 1
+#endif
+
+/*
+ * Flags for isc_mem_create2()calls.
+ */
+#define ISC_MEMFLAG_NOLOCK 0x00000001 /* no lock is necessary */
+#define ISC_MEMFLAG_INTERNAL 0x00000002 /* use internal malloc */
+#if ISC_MEM_USE_INTERNAL_MALLOC
+#define ISC_MEMFLAG_DEFAULT ISC_MEMFLAG_INTERNAL
+#else
+#define ISC_MEMFLAG_DEFAULT 0
+#endif
+
+
+#define isc_mem_get(c, s) isc__mem_get((c), (s) _ISC_MEM_FILELINE)
+#define isc_mem_allocate(c, s) isc__mem_allocate((c), (s) _ISC_MEM_FILELINE)
+#define isc_mem_strdup(c, p) isc__mem_strdup((c), (p) _ISC_MEM_FILELINE)
+#define isc_mempool_get(c) isc__mempool_get((c) _ISC_MEM_FILELINE)
+
+/*%
+ * isc_mem_putanddetach() is a convienence function for use where you
+ * have a structure with an attached memory context.
+ *
+ * Given:
+ *
+ * \code
+ * struct {
+ * ...
+ * isc_mem_t *mctx;
+ * ...
+ * } *ptr;
+ *
+ * isc_mem_t *mctx;
+ *
+ * isc_mem_putanddetach(&ptr->mctx, ptr, sizeof(*ptr));
+ * \endcode
+ *
+ * is the equivalent of:
+ *
+ * \code
+ * mctx = NULL;
+ * isc_mem_attach(ptr->mctx, &mctx);
+ * isc_mem_detach(&ptr->mctx);
+ * isc_mem_put(mctx, ptr, sizeof(*ptr));
+ * isc_mem_detach(&mctx);
+ * \endcode
+ */
+
+#if ISC_MEM_DEBUG
+#define isc_mem_put(c, p, s) \
+ do { \
+ isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE); \
+ (p) = NULL; \
+ } while (0)
+#define isc_mem_putanddetach(c, p, s) \
+ do { \
+ isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE); \
+ (p) = NULL; \
+ } while (0)
+#define isc_mem_free(c, p) \
+ do { \
+ isc__mem_free((c), (p) _ISC_MEM_FILELINE); \
+ (p) = NULL; \
+ } while (0)
+#define isc_mempool_put(c, p) \
+ do { \
+ isc__mempool_put((c), (p) _ISC_MEM_FILELINE); \
+ (p) = NULL; \
+ } while (0)
+#else
+#define isc_mem_put(c, p, s) isc__mem_put((c), (p), (s) _ISC_MEM_FILELINE)
+#define isc_mem_putanddetach(c, p, s) \
+ isc__mem_putanddetach((c), (p), (s) _ISC_MEM_FILELINE)
+#define isc_mem_free(c, p) isc__mem_free((c), (p) _ISC_MEM_FILELINE)
+#define isc_mempool_put(c, p) isc__mempool_put((c), (p) _ISC_MEM_FILELINE)
+#endif
+
+/*@{*/
+isc_result_t
+isc_mem_create(size_t max_size, size_t target_size,
+ isc_mem_t **mctxp);
+
+isc_result_t
+isc_mem_create2(size_t max_size, size_t target_size,
+ isc_mem_t **mctxp, unsigned int flags);
+
+isc_result_t
+isc_mem_createx(size_t max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree,
+ void *arg, isc_mem_t **mctxp);
+
+isc_result_t
+isc_mem_createx2(size_t max_size, size_t target_size,
+ isc_memalloc_t memalloc, isc_memfree_t memfree,
+ void *arg, isc_mem_t **mctxp, unsigned int flags);
+
+/*!<
+ * \brief Create a memory context.
+ *
+ * 'max_size' and 'target_size' are tuning parameters. When
+ * ISC_MEMFLAG_INTERNAL is set, allocations smaller than 'max_size'
+ * will be satisfied by getting blocks of size 'target_size' from the
+ * system allocator and breaking them up into pieces; larger allocations
+ * will use the system allocator directly. If 'max_size' and/or
+ * 'target_size' are zero, default values will be * used. When
+ * ISC_MEMFLAG_INTERNAL is not set, 'target_size' is ignored.
+ *
+ * 'max_size' is also used to size the statistics arrays and the array
+ * used to record active memory when ISC_MEM_DEBUGRECORD is set. Settin
+ * 'max_size' too low can have detrimental effects on performance.
+ *
+ * A memory context created using isc_mem_createx() will obtain
+ * memory from the system by calling 'memalloc' and 'memfree',
+ * passing them the argument 'arg'. A memory context created
+ * using isc_mem_create() will use the standard library malloc()
+ * and free().
+ *
+ * If ISC_MEMFLAG_NOLOCK is set in 'flags', the corresponding memory context
+ * will be accessed without locking. The user who creates the context must
+ * ensure there be no race. Since this can be a source of bug, it is generally
+ * inadvisable to use this flag unless the user is very sure about the race
+ * condition and the access to the object is highly performance sensitive.
+ *
+ * Requires:
+ * mctxp != NULL && *mctxp == NULL */
+/*@}*/
+
+/*@{*/
+void
+isc_mem_attach(isc_mem_t *, isc_mem_t **);
+void
+isc_mem_detach(isc_mem_t **);
+/*!<
+ * \brief Attach to / detach from a memory context.
+ *
+ * This is intended for applications that use multiple memory contexts
+ * in such a way that it is not obvious when the last allocations from
+ * a given context has been freed and destroying the context is safe.
+ *
+ * Most applications do not need to call these functions as they can
+ * simply create a single memory context at the beginning of main()
+ * and destroy it at the end of main(), thereby guaranteeing that it
+ * is not destroyed while there are outstanding allocations.
+ */
+/*@}*/
+
+void
+isc_mem_destroy(isc_mem_t **);
+/*%<
+ * Destroy a memory context.
+ */
+
+isc_result_t
+isc_mem_ondestroy(isc_mem_t *ctx,
+ isc_task_t *task,
+ isc_event_t **event);
+/*%<
+ * Request to be notified with an event when a memory context has
+ * been successfully destroyed.
+ */
+
+void
+isc_mem_stats(isc_mem_t *mctx, FILE *out);
+/*%<
+ * Print memory usage statistics for 'mctx' on the stream 'out'.
+ */
+
+void
+isc_mem_setdestroycheck(isc_mem_t *mctx,
+ isc_boolean_t on);
+/*%<
+ * If 'on' is ISC_TRUE, 'mctx' will check for memory leaks when
+ * destroyed and abort the program if any are present.
+ */
+
+/*@{*/
+void
+isc_mem_setquota(isc_mem_t *, size_t);
+size_t
+isc_mem_getquota(isc_mem_t *);
+/*%<
+ * Set/get the memory quota of 'mctx'. This is a hard limit
+ * on the amount of memory that may be allocated from mctx;
+ * if it is exceeded, allocations will fail.
+ */
+/*@}*/
+
+size_t
+isc_mem_inuse(isc_mem_t *mctx);
+/*%<
+ * Get an estimate of the number of memory in use in 'mctx', in bytes.
+ * This includes quantization overhead, but does not include memory
+ * allocated from the system but not yet used.
+ */
+
+void
+isc_mem_setwater(isc_mem_t *mctx, isc_mem_water_t water, void *water_arg,
+ size_t hiwater, size_t lowater);
+/*%<
+ * Set high and low water marks for this memory context.
+ *
+ * When the memory
+ * usage of 'mctx' exceeds 'hiwater', '(water)(water_arg, #ISC_MEM_HIWATER)'
+ * will be called. When the usage drops below 'lowater', 'water' will
+ * again be called, this time with #ISC_MEM_LOWATER.
+ *
+ * If 'water' is NULL then 'water_arg', 'hi_water' and 'lo_water' are
+ * ignored and the state is reset.
+ *
+ * Requires:
+ *
+ * 'water' is not NULL.
+ * hi_water >= lo_water
+ */
+
+void
+isc_mem_printactive(isc_mem_t *mctx, FILE *file);
+/*%<
+ * Print to 'file' all active memory in 'mctx'.
+ *
+ * Requires ISC_MEM_DEBUGRECORD to have been set.
+ */
+
+void
+isc_mem_printallactive(FILE *file);
+/*%<
+ * Print to 'file' all active memory in all contexts.
+ *
+ * Requires ISC_MEM_DEBUGRECORD to have been set.
+ */
+
+void
+isc_mem_checkdestroyed(FILE *file);
+/*%<
+ * Check that all memory contexts have been destroyed.
+ * Prints out those that have not been.
+ * Fatally fails if there are still active contexts.
+ */
+
+/*
+ * Memory pools
+ */
+
+isc_result_t
+isc_mempool_create(isc_mem_t *mctx, size_t size, isc_mempool_t **mpctxp);
+/*%<
+ * Create a memory pool.
+ *
+ * Requires:
+ *\li mctx is a valid memory context.
+ *\li size > 0
+ *\li mpctxp != NULL and *mpctxp == NULL
+ *
+ * Defaults:
+ *\li maxalloc = UINT_MAX
+ *\li freemax = 1
+ *\li fillcount = 1
+ *
+ * Returns:
+ *\li #ISC_R_NOMEMORY -- not enough memory to create pool
+ *\li #ISC_R_SUCCESS -- all is well.
+ */
+
+void
+isc_mempool_destroy(isc_mempool_t **mpctxp);
+/*%<
+ * Destroy a memory pool.
+ *
+ * Requires:
+ *\li mpctxp != NULL && *mpctxp is a valid pool.
+ *\li The pool has no un"put" allocations outstanding
+ */
+
+void
+isc_mempool_setname(isc_mempool_t *mpctx, const char *name);
+/*%<
+ * Associate a name with a memory pool. At most 15 characters may be used.
+ *
+ * Requires:
+ *\li mpctx is a valid pool.
+ *\li name != NULL;
+ */
+
+void
+isc_mempool_associatelock(isc_mempool_t *mpctx, isc_mutex_t *lock);
+/*%<
+ * Associate a lock with this memory pool.
+ *
+ * This lock is used when getting or putting items using this memory pool,
+ * and it is also used to set or get internal state via the isc_mempool_get*()
+ * and isc_mempool_set*() set of functions.
+ *
+ * Mutiple pools can each share a single lock. For instance, if "manager"
+ * type object contained pools for various sizes of events, and each of
+ * these pools used a common lock. Note that this lock must NEVER be used
+ * by other than mempool routines once it is given to a pool, since that can
+ * easily cause double locking.
+ *
+ * Requires:
+ *
+ *\li mpctpx is a valid pool.
+ *
+ *\li lock != NULL.
+ *
+ *\li No previous lock is assigned to this pool.
+ *
+ *\li The lock is initialized before calling this function via the normal
+ * means of doing that.
+ */
+
+/*
+ * The following functions get/set various parameters. Note that due to
+ * the unlocked nature of pools these are potentially random values unless
+ * the imposed externally provided locking protocols are followed.
+ *
+ * Also note that the quota limits will not always take immediate effect.
+ * For instance, setting "maxalloc" to a number smaller than the currently
+ * allocated count is permitted. New allocations will be refused until
+ * the count drops below this threshold.
+ *
+ * All functions require (in addition to other requirements):
+ * mpctx is a valid memory pool
+ */
+
+unsigned int
+isc_mempool_getfreemax(isc_mempool_t *mpctx);
+/*%<
+ * Returns the maximum allowed size of the free list.
+ */
+
+void
+isc_mempool_setfreemax(isc_mempool_t *mpctx, unsigned int limit);
+/*%<
+ * Sets the maximum allowed size of the free list.
+ */
+
+unsigned int
+isc_mempool_getfreecount(isc_mempool_t *mpctx);
+/*%<
+ * Returns current size of the free list.
+ */
+
+unsigned int
+isc_mempool_getmaxalloc(isc_mempool_t *mpctx);
+/*!<
+ * Returns the maximum allowed number of allocations.
+ */
+
+void
+isc_mempool_setmaxalloc(isc_mempool_t *mpctx, unsigned int limit);
+/*%<
+ * Sets the maximum allowed number of allocations.
+ *
+ * Additional requirements:
+ *\li limit > 0
+ */
+
+unsigned int
+isc_mempool_getallocated(isc_mempool_t *mpctx);
+/*%<
+ * Returns the number of items allocated from this pool.
+ */
+
+unsigned int
+isc_mempool_getfillcount(isc_mempool_t *mpctx);
+/*%<
+ * Returns the number of items allocated as a block from the parent memory
+ * context when the free list is empty.
+ */
+
+void
+isc_mempool_setfillcount(isc_mempool_t *mpctx, unsigned int limit);
+/*%<
+ * Sets the fillcount.
+ *
+ * Additional requirements:
+ *\li limit > 0
+ */
+
+
+/*
+ * Pseudo-private functions for use via macros. Do not call directly.
+ */
+void *
+isc__mem_get(isc_mem_t *, size_t _ISC_MEM_FLARG);
+void
+isc__mem_putanddetach(isc_mem_t **, void *,
+ size_t _ISC_MEM_FLARG);
+void
+isc__mem_put(isc_mem_t *, void *, size_t _ISC_MEM_FLARG);
+void *
+isc__mem_allocate(isc_mem_t *, size_t _ISC_MEM_FLARG);
+void
+isc__mem_free(isc_mem_t *, void * _ISC_MEM_FLARG);
+char *
+isc__mem_strdup(isc_mem_t *, const char *_ISC_MEM_FLARG);
+void *
+isc__mempool_get(isc_mempool_t * _ISC_MEM_FLARG);
+void
+isc__mempool_put(isc_mempool_t *, void * _ISC_MEM_FLARG);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_MEM_H */
diff --git a/lib/isc/include/isc/msgcat.h b/lib/isc/include/isc/msgcat.h
new file mode 100644
index 000000000000..813b57c3b63e
--- /dev/null
+++ b/lib/isc/include/isc/msgcat.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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.9.18.2 2005/04/29 00:16:59 marka 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/lib/isc/include/isc/msgs.h b/lib/isc/include/isc/msgs.h
new file mode 100644
index 000000000000..97b21085eddf
--- /dev/null
+++ b/lib/isc/include/isc/msgs.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000-2003 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 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.9.18.2 2005/04/29 00:16:59 marka Exp $ */
+
+#ifndef ISC_MSGS_H
+#define ISC_MSGS_H 1
+
+/*! \file */
+
+#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_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 1420 /*%< setsockopt(SO_ACCEPTFILTER): %s */
+
+#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/lib/isc/include/isc/mutexblock.h b/lib/isc/include/isc/mutexblock.h
new file mode 100644
index 000000000000..fa244c945e42
--- /dev/null
+++ b/lib/isc/include/isc/mutexblock.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: mutexblock.h,v 1.11.18.2 2005/04/29 00:17:00 marka Exp $ */
+
+#ifndef ISC_MUTEXBLOCK_H
+#define ISC_MUTEXBLOCK_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_mutexblock_init(isc_mutex_t *block, unsigned int count);
+/*%<
+ * Initialize a block of locks. If an error occurs all initialized locks
+ * will be destroyed, if possible.
+ *
+ * Requires:
+ *
+ *\li block != NULL
+ *
+ *\li count > 0
+ *
+ * Returns:
+ *
+ *\li Any code isc_mutex_init() can return is a valid return for this
+ * function.
+ */
+
+isc_result_t
+isc_mutexblock_destroy(isc_mutex_t *block, unsigned int count);
+/*%<
+ * Destroy a block of locks.
+ *
+ * Requires:
+ *
+ *\li block != NULL
+ *
+ *\li count > 0
+ *
+ *\li Each lock in the block be initialized via isc_mutex_init() or
+ * the whole block was initialized via isc_mutex_initblock().
+ *
+ * Returns:
+ *
+ *\li Any code isc_mutex_init() can return is a valid return for this
+ * function.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_MUTEXBLOCK_H */
diff --git a/lib/isc/include/isc/netaddr.h b/lib/isc/include/isc/netaddr.h
new file mode 100644
index 000000000000..06d063e70bad
--- /dev/null
+++ b/lib/isc/include/isc/netaddr.h
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 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 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.25.18.5 2005/07/28 04:58:47 marka Exp $ */
+
+#ifndef ISC_NETADDR_H
+#define ISC_NETADDR_H 1
+
+/*! \file */
+
+#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);
+
+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'. 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_NOTIMPLENTED unsupported family
+ * ISC_R_FAILURE extra bits.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_NETADDR_H */
diff --git a/lib/isc/include/isc/netscope.h b/lib/isc/include/isc/netscope.h
new file mode 100644
index 000000000000..d9bea54fbd7c
--- /dev/null
+++ b/lib/isc/include/isc/netscope.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2002 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 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.5.18.2 2005/04/29 00:17:00 marka Exp $ */
+
+#ifndef ISC_NETSCOPE_H
+#define ISC_NETSCOPE_H 1
+
+/*! \file */
+
+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_NETADDR_H */
diff --git a/lib/isc/include/isc/ondestroy.h b/lib/isc/include/isc/ondestroy.h
new file mode 100644
index 000000000000..035873c5f513
--- /dev/null
+++ b/lib/isc/include/isc/ondestroy.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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.8.18.2 2005/04/29 00:17:00 marka Exp $ */
+
+#ifndef ISC_ONDESTROY_H
+#define ISC_ONDESTROY_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*! \file
+ * 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/lib/isc/include/isc/os.h b/lib/isc/include/isc/os.h
new file mode 100644
index 000000000000..b2b76d559e5e
--- /dev/null
+++ b/lib/isc/include/isc/os.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: os.h,v 1.6.18.2 2005/04/29 00:17:00 marka Exp $ */
+
+#ifndef ISC_OS_H
+#define ISC_OS_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+
+ISC_LANG_BEGINDECLS
+
+unsigned int
+isc_os_ncpus(void);
+/*%<
+ * Return the number of CPUs available on the system, or 1 if this cannot
+ * be determined.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_OS_H */
diff --git a/lib/isc/include/isc/parseint.h b/lib/isc/include/isc/parseint.h
new file mode 100644
index 000000000000..6940add40394
--- /dev/null
+++ b/lib/isc/include/isc/parseint.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001, 2002 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 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: parseint.h,v 1.3.18.2 2005/04/29 00:17:00 marka Exp $ */
+
+#ifndef ISC_PARSEINT_H
+#define ISC_PARSEINT_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*! \file
+ * \brief Parse integers, in a saner way than atoi() or strtoul() do.
+ */
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_parse_uint32(isc_uint32_t *uip, const char *string, int base);
+
+isc_result_t
+isc_parse_uint16(isc_uint16_t *uip, const char *string, int base);
+
+isc_result_t
+isc_parse_uint8(isc_uint8_t *uip, const char *string, int base);
+/*%<
+ * Parse the null-terminated string 'string' containing a base 'base'
+ * integer, storing the result in '*uip'.
+ * The base is interpreted
+ * as in strtoul(). Unlike strtoul(), leading whitespace, minus or
+ * plus signs are not accepted, and all errors (including overflow)
+ * are reported uniformly through the return value.
+ *
+ * Requires:
+ *\li 'string' points to a null-terminated string
+ *\li 0 <= 'base' <= 36
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_BADNUMBER The string is not numeric (in the given base)
+ *\li #ISC_R_RANGE The number is not representable as the requested type.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_PARSEINT_H */
diff --git a/lib/isc/include/isc/platform.h.in b/lib/isc/include/isc/platform.h.in
new file mode 100644
index 000000000000..0531edfa020e
--- /dev/null
+++ b/lib/isc/include/isc/platform.h.in
@@ -0,0 +1,306 @@
+/*
+ * 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: platform.h.in,v 1.34.18.9 2007/09/13 05:04:01 each Exp $ */
+
+#ifndef ISC_PLATFORM_H
+#define ISC_PLATFORM_H 1
+
+/*! \file */
+
+/*****
+ ***** Platform-dependent defines.
+ *****/
+
+/*
+ * Define if the platform has <strings.h>.
+ */
+@ISC_PLATFORM_HAVESTRINGSH@
+
+/***
+ *** Network.
+ ***/
+
+/*! \brief
+ * Define if this system needs the <netinet/in6.h> header file included
+ * for full IPv6 support (pretty much only UnixWare).
+ */
+@ISC_PLATFORM_NEEDNETINETIN6H@
+
+/*! \brief
+ * Define if this system needs the <netinet6/in6.h> header file included
+ * to support in6_pkinfo (pretty much only BSD/OS).
+ */
+@ISC_PLATFORM_NEEDNETINET6IN6H@
+
+/*! \brief
+ * If sockaddrs on this system have an sa_len field, ISC_PLATFORM_HAVESALEN
+ * will be defined.
+ */
+@ISC_PLATFORM_HAVESALEN@
+
+/*! \brief
+ * If this system has the IPv6 structure definitions, ISC_PLATFORM_HAVEIPV6
+ * will be defined.
+ */
+@ISC_PLATFORM_HAVEIPV6@
+
+/*! \brief
+ * If this system is missing in6addr_any, ISC_PLATFORM_NEEDIN6ADDRANY will
+ * be defined.
+ */
+@ISC_PLATFORM_NEEDIN6ADDRANY@
+
+/*! \brief
+ * If this system is missing in6addr_loopback, ISC_PLATFORM_NEEDIN6ADDRLOOPBACK
+ * will be defined.
+ */
+@ISC_PLATFORM_NEEDIN6ADDRLOOPBACK@
+
+/*! \brief
+ * If this system has in6_pktinfo, ISC_PLATFORM_HAVEIN6PKTINFO will be
+ * defined.
+ */
+@ISC_PLATFORM_HAVEIN6PKTINFO@
+
+/*! \brief
+ * If this system has in_addr6, rather than in6_addr, ISC_PLATFORM_HAVEINADDR6
+ * will be defined.
+ */
+@ISC_PLATFORM_HAVEINADDR6@
+
+/*! \brief
+ * If this system has sin6_scope_id, ISC_PLATFORM_HAVESCOPEID will be defined.
+ */
+@ISC_PLATFORM_HAVESCOPEID@
+
+/*! \brief
+ * If this system needs inet_ntop(), ISC_PLATFORM_NEEDNTOP will be defined.
+ */
+@ISC_PLATFORM_NEEDNTOP@
+
+/*! \brief
+ * If this system needs inet_pton(), ISC_PLATFORM_NEEDPTON will be defined.
+ */
+@ISC_PLATFORM_NEEDPTON@
+
+/*! \brief
+ * If this system needs inet_aton(), ISC_PLATFORM_NEEDATON will be defined.
+ */
+@ISC_PLATFORM_NEEDATON@
+
+/*! \brief
+ * If this system needs in_port_t, ISC_PLATFORM_NEEDPORTT will be defined.
+ */
+@ISC_PLATFORM_NEEDPORTT@
+
+/*! \brief
+ * If the system needs strsep(), ISC_PLATFORM_NEEDSTRSEP will be defined.
+ */
+@ISC_PLATFORM_NEEDSTRSEP@
+
+/*! \brief
+ * If the system needs strlcpy(), ISC_PLATFORM_NEEDSTRLCPY will be defined.
+ */
+@ISC_PLATFORM_NEEDSTRLCPY@
+
+/*! \brief
+ * If the system needs strlcat(), ISC_PLATFORM_NEEDSTRLCAT will be defined.
+ */
+@ISC_PLATFORM_NEEDSTRLCAT@
+
+/*! \brief
+ * Define either ISC_PLATFORM_BSD44MSGHDR or ISC_PLATFORM_BSD43MSGHDR.
+ */
+@ISC_PLATFORM_MSGHDRFLAVOR@
+
+/*! \brief
+ * Define if PTHREAD_ONCE_INIT should be surrounded by braces to
+ * prevent compiler warnings (such as with gcc on Solaris 2.8).
+ */
+@ISC_PLATFORM_BRACEPTHREADONCEINIT@
+
+/*! \brief
+ * Define on some UnixWare systems to fix erroneous definitions of various
+ * IN6_IS_ADDR_* macros.
+ */
+@ISC_PLATFORM_FIXIN6ISADDR@
+
+/*
+ *** Printing.
+ ***/
+
+/*! \brief
+ * If this system needs vsnprintf() and snprintf(), ISC_PLATFORM_NEEDVSNPRINTF
+ * will be defined.
+ */
+@ISC_PLATFORM_NEEDVSNPRINTF@
+
+/*! \brief
+ * If this system need a modern sprintf() that returns (int) not (char*).
+ */
+@ISC_PLATFORM_NEEDSPRINTF@
+
+/*! \brief
+ * The printf format string modifier to use with isc_uint64_t values.
+ */
+@ISC_PLATFORM_QUADFORMAT@
+
+/*! \brief
+ * Defined if we are using threads.
+ */
+@ISC_PLATFORM_USETHREADS@
+
+/*! \brief
+ * Defined if unistd.h does not cause fd_set to be delared.
+ */
+@ISC_PLATFORM_NEEDSYSSELECTH@
+
+/*! \brief
+ * Type used for resource limits.
+ */
+@ISC_PLATFORM_RLIMITTYPE@
+
+/*! \brief
+ * Define if your compiler supports "long long int".
+ */
+@ISC_PLATFORM_HAVELONGLONG@
+
+/*! \brief
+ * Define if the system has struct lifconf which is a extended struct ifconf
+ * for IPv6.
+ */
+@ISC_PLATFORM_HAVELIFCONF@
+
+/*! \brief
+ * Define if the system has struct if_laddrconf which is a extended struct
+ * ifconf for IPv6.
+ */
+@ISC_PLATFORM_HAVEIF_LADDRCONF@
+
+/*! \brief
+ * Define if the system has struct if_laddrreq.
+ */
+@ISC_PLATFORM_HAVEIF_LADDRREQ@
+
+/*! \brief
+ * Used to control how extern data is linked; needed for Win32 platforms.
+ */
+@ISC_PLATFORM_USEDECLSPEC@
+
+/*! \brief
+ * Define if the system supports if_nametoindex.
+ */
+@ISC_PLATFORM_HAVEIFNAMETOINDEX@
+
+/*! \brief
+ * Define if this system needs strtoul.
+ */
+@ISC_PLATFORM_NEEDSTRTOUL@
+
+/*! \brief
+ * Define if this system needs memmove.
+ */
+@ISC_PLATFORM_NEEDMEMMOVE@
+
+/*
+ * Define if the platform has <sys/un.h>.
+ */
+@ISC_PLATFORM_HAVESYSUNH@
+
+/*
+ * If the "xadd" operation is available on this architecture,
+ * ISC_PLATFORM_HAVEXADD will be defined.
+ */
+@ISC_PLATFORM_HAVEXADD@
+
+/*
+ * If the "atomic swap" operation is available on this architecture,
+ * ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
+ */
+@ISC_PLATFORM_HAVEATOMICSTORE@
+
+/*
+ * If the "compare-and-exchange" operation is available on this architecture,
+ * ISC_PLATFORM_HAVECMPXCHG will be defined.
+ */
+@ISC_PLATFORM_HAVECMPXCHG@
+
+/*
+ * Define if gcc ASM extension is available
+ */
+@ISC_PLATFORM_USEGCCASM@
+
+/*
+ * Define if Tru64 style ASM syntax must be used.
+ */
+@ISC_PLATFORM_USEOSFASM@
+
+/*
+ * Define if the standard __asm function must be used.
+ */
+@ISC_PLATFORM_USESTDASM@
+
+/*
+ * Define if MacOS style of PPC assembly must be used.
+ * e.g. "r6", not "6", for register six.
+ */
+@ISC_PLATFORM_USEMACASM@
+
+#ifndef ISC_PLATFORM_USEDECLSPEC
+#define LIBISC_EXTERNAL_DATA
+#define LIBDNS_EXTERNAL_DATA
+#define LIBISCCC_EXTERNAL_DATA
+#define LIBISCCFG_EXTERNAL_DATA
+#define LIBBIND9_EXTERNAL_DATA
+#else /*! \brief ISC_PLATFORM_USEDECLSPEC */
+#ifdef LIBISC_EXPORTS
+#define LIBISC_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBISC_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#ifdef LIBDNS_EXPORTS
+#define LIBDNS_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBDNS_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#ifdef LIBISCCC_EXPORTS
+#define LIBISCCC_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBISCCC_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#ifdef LIBISCCFG_EXPORTS
+#define LIBISCCFG_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBISCCFG_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#ifdef LIBBIND9_EXPORTS
+#define LIBBIND9_EXTERNAL_DATA __declspec(dllexport)
+#else
+#define LIBBIND9_EXTERNAL_DATA __declspec(dllimport)
+#endif
+#endif /*! \brief ISC_PLATFORM_USEDECLSPEC */
+
+/*
+ * Tell emacs to use C mode for this file.
+ *
+ * Local Variables:
+ * mode: c
+ * End:
+ */
+
+#endif /* ISC_PLATFORM_H */
diff --git a/lib/isc/include/isc/print.h b/lib/isc/include/isc/print.h
new file mode 100644
index 000000000000..95c6b1c84b22
--- /dev/null
+++ b/lib/isc/include/isc/print.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2001, 2003 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 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.19.18.3 2005/06/08 02:07:56 marka Exp $ */
+
+#ifndef ISC_PRINT_H
+#define ISC_PRINT_H 1
+
+/*! \file */
+
+/***
+ *** 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/lib/isc/include/isc/quota.h b/lib/isc/include/isc/quota.h
new file mode 100644
index 000000000000..6f95cd5fc4f3
--- /dev/null
+++ b/lib/isc/include/isc/quota.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: quota.h,v 1.10.18.4 2005/08/11 15:01:54 marka Exp $ */
+
+#ifndef ISC_QUOTA_H
+#define ISC_QUOTA_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file isc/quota.h
+ *
+ * \brief The isc_quota_t object is a simple helper object for implementing
+ * quotas on things like the number of simultaneous connections to
+ * a server. It keeps track of the amount of quota in use, and
+ * encapsulates the locking necessary to allow multiple tasks to
+ * share a quota.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/types.h>
+
+/*****
+ ***** Types.
+ *****/
+
+ISC_LANG_BEGINDECLS
+
+/*% isc_quota structure */
+struct isc_quota {
+ isc_mutex_t lock; /*%< Locked by lock. */
+ int max;
+ int used;
+ int soft;
+};
+
+isc_result_t
+isc_quota_init(isc_quota_t *quota, int max);
+/*%<
+ * Initialize a quota object.
+ *
+ * Returns:
+ * ISC_R_SUCCESS
+ * Other error Lock creation failed.
+ */
+
+void
+isc_quota_destroy(isc_quota_t *quota);
+/*%<
+ * Destroy a quota object.
+ */
+
+void
+isc_quota_soft(isc_quota_t *quota, int soft);
+/*%<
+ * Set a soft quota.
+ */
+
+void
+isc_quota_max(isc_quota_t *quota, int max);
+/*%<
+ * Re-set a maximum quota.
+ */
+
+isc_result_t
+isc_quota_reserve(isc_quota_t *quota);
+/*%<
+ * Attempt to reserve one unit of 'quota'.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS Success
+ * \li #ISC_R_SOFTQUOTA Success soft quota reached
+ * \li #ISC_R_QUOTA Quota is full
+ */
+
+void
+isc_quota_release(isc_quota_t *quota);
+/*%<
+ * Release one unit of quota.
+ */
+
+isc_result_t
+isc_quota_attach(isc_quota_t *quota, isc_quota_t **p);
+/*%<
+ * Like isc_quota_reserve, and also attaches '*p' to the
+ * quota if successful (ISC_R_SUCCESS or ISC_R_SOFTQUOTA).
+ */
+
+void
+isc_quota_detach(isc_quota_t **p);
+/*%<
+ * Like isc_quota_release, and also detaches '*p' from the
+ * quota.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_QUOTA_H */
diff --git a/lib/isc/include/isc/random.h b/lib/isc/include/isc/random.h
new file mode 100644
index 000000000000..c5cef8bdbfc5
--- /dev/null
+++ b/lib/isc/include/isc/random.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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.12.18.2 2005/04/29 00:17:01 marka Exp $ */
+
+#ifndef ISC_RANDOM_H
+#define ISC_RANDOM_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*! \file
+ * \brief Implements a random state pool which will let the caller return a
+ * series of possibly non-reproducable 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/lib/isc/include/isc/ratelimiter.h b/lib/isc/include/isc/ratelimiter.h
new file mode 100644
index 000000000000..1944754b05e0
--- /dev/null
+++ b/lib/isc/include/isc/ratelimiter.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2002 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 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: ratelimiter.h,v 1.15.18.2 2005/04/29 00:17:01 marka Exp $ */
+
+#ifndef ISC_RATELIMITER_H
+#define ISC_RATELIMITER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \brief A rate limiter is a mechanism for dispatching events at a limited
+ * rate. This is intended to be used when sending zone maintenance
+ * SOA queries, NOTIFY messages, etc.
+ */
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+/*****
+ ***** Functions.
+ *****/
+
+isc_result_t
+isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
+ isc_task_t *task, isc_ratelimiter_t **ratelimiterp);
+/*%<
+ * Create a rate limiter. The execution interval is initially undefined.
+ */
+
+isc_result_t
+isc_ratelimiter_setinterval(isc_ratelimiter_t *rl, isc_interval_t *interval);
+/*!<
+ * Set the mininum interval between event executions.
+ * The interval value is copied, so the caller need not preserve it.
+ *
+ * Requires:
+ * '*interval' is a nonzero interval.
+ */
+
+void
+isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t perint);
+/*%<
+ * Set the number of events processed per interval timer tick.
+ * If 'perint' is zero it is treated as 1.
+ */
+
+isc_result_t
+isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
+ isc_event_t **eventp);
+/*%<
+ * Queue an event for rate-limited execution.
+ *
+ * This is similar
+ * to doing an isc_task_send() to the 'task', except that the
+ * execution may be delayed to achieve the desired rate of
+ * execution.
+ *
+ * '(*eventp)->ev_sender' is used to hold the task. The caller
+ * must ensure that the task exists until the event is delivered.
+ *
+ * Requires:
+ *\li An interval has been set by calling
+ * isc_ratelimiter_setinterval().
+ *
+ *\li 'task' to be non NULL.
+ *\li '(*eventp)->ev_sender' to be NULL.
+ */
+
+void
+isc_ratelimiter_shutdown(isc_ratelimiter_t *ratelimiter);
+/*%<
+ * Shut down a rate limiter.
+ *
+ * Ensures:
+ *\li All events that have not yet been
+ * dispatched to the task are dispatched immediately with
+ * the #ISC_EVENTATTR_CANCELED bit set in ev_attributes.
+ *
+ *\li Further attempts to enqueue events will fail with
+ * #ISC_R_SHUTTINGDOWN.
+ *
+ *\li The reatelimiter is no longer attached to its task.
+ */
+
+void
+isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target);
+/*%<
+ * Attach to a rate limiter.
+ */
+
+void
+isc_ratelimiter_detach(isc_ratelimiter_t **ratelimiterp);
+/*%<
+ * Detach from a rate limiter.
+ */
+
+isc_result_t
+isc_ratelimiter_stall(isc_ratelimiter_t *rl);
+/*%<
+ * Stall event processing.
+ */
+
+isc_result_t
+isc_ratelimiter_release(isc_ratelimiter_t *rl);
+/*%<
+ * Release a stalled rate limiter.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RATELIMITER_H */
diff --git a/lib/isc/include/isc/refcount.h b/lib/isc/include/isc/refcount.h
new file mode 100644
index 000000000000..b930465514c5
--- /dev/null
+++ b/lib/isc/include/isc/refcount.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2001, 2003 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 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: refcount.h,v 1.6.18.5 2005/07/12 01:22:31 marka Exp $ */
+
+#ifndef ISC_REFCOUNT_H
+#define ISC_REFCOUNT_H 1
+
+#include <isc/atomic.h>
+#include <isc/lang.h>
+#include <isc/mutex.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+#include <isc/util.h>
+
+/*! \file
+ * \brief Implements a locked reference counter.
+ *
+ * These functions may actually be
+ * implemented using macros, and implementations of these macros are below.
+ * The isc_refcount_t type should not be accessed directly, as its contents
+ * depend on the implementation.
+ */
+
+ISC_LANG_BEGINDECLS
+
+/*
+ * Function prototypes
+ */
+
+/*
+ * isc_result_t
+ * isc_refcount_init(isc_refcount_t *ref, unsigned int n);
+ *
+ * Initialize the reference counter. There will be 'n' initial references.
+ *
+ * Requires:
+ * ref != NULL
+ */
+
+/*
+ * void
+ * isc_refcount_destroy(isc_refcount_t *ref);
+ *
+ * Destroys a reference counter.
+ *
+ * Requires:
+ * ref != NULL
+ * The number of references is 0.
+ */
+
+/*
+ * void
+ * isc_refcount_increment(isc_refcount_t *ref, unsigned int *targetp);
+ * isc_refcount_increment0(isc_refcount_t *ref, unsigned int *targetp);
+ *
+ * Increments the reference count, returning the new value in targetp if it's
+ * not NULL. The reference counter typically begins with the initial counter
+ * of 1, and will be destroyed once the counter reaches 0. Thus,
+ * isc_refcount_increment() additionally requires the previous counter be
+ * larger than 0 so that an error which violates the usage can be easily
+ * caught. isc_refcount_increment0() does not have this restriction.
+ *
+ * Requires:
+ * ref != NULL.
+ */
+
+/*
+ * void
+ * isc_refcount_decrement(isc_refcount_t *ref, unsigned int *targetp);
+ *
+ * Decrements the reference count, returning the new value in targetp if it's
+ * not NULL.
+ *
+ * Requires:
+ * ref != NULL.
+ */
+
+
+/*
+ * Sample implementations
+ */
+#ifdef ISC_PLATFORM_USETHREADS
+#ifdef ISC_PLATFORM_HAVEXADD
+
+#define ISC_REFCOUNT_HAVEATOMIC 1
+
+typedef struct isc_refcount {
+ isc_int32_t refs;
+} isc_refcount_t;
+
+#define isc_refcount_destroy(rp) (REQUIRE((rp)->refs == 0))
+#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
+
+#define isc_refcount_increment0(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, 1); \
+ if (_tmp != NULL) \
+ *_tmp = prev + 1; \
+ } while (0)
+
+#define isc_refcount_increment(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, 1); \
+ REQUIRE(prev > 0); \
+ if (_tmp != NULL) \
+ *_tmp = prev + 1; \
+ } while (0)
+
+#define isc_refcount_decrement(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ isc_int32_t prev; \
+ prev = isc_atomic_xadd(&(rp)->refs, -1); \
+ REQUIRE(prev > 0); \
+ if (_tmp != NULL) \
+ *_tmp = prev - 1; \
+ } while (0)
+
+#else /* ISC_PLATFORM_HAVEXADD */
+
+typedef struct isc_refcount {
+ int refs;
+ isc_mutex_t lock;
+} isc_refcount_t;
+
+/*% Destroys a reference counter. */
+#define isc_refcount_destroy(rp) \
+ do { \
+ REQUIRE((rp)->refs == 0); \
+ DESTROYLOCK(&(rp)->lock); \
+ } while (0)
+
+#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
+
+/*% Increments the reference count, returning the new value in targetp if it's not NULL. */
+#define isc_refcount_increment0(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ LOCK(&(rp)->lock); \
+ ++((rp)->refs); \
+ if (_tmp != NULL) \
+ *_tmp = ((rp)->refs); \
+ UNLOCK(&(rp)->lock); \
+ } while (0)
+
+#define isc_refcount_increment(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ LOCK(&(rp)->lock); \
+ REQUIRE((rp)->refs > 0); \
+ ++((rp)->refs); \
+ if (_tmp != NULL) \
+ *_tmp = ((rp)->refs); \
+ UNLOCK(&(rp)->lock); \
+ } while (0)
+
+/*% Decrements the reference count, returning the new value in targetp if it's not NULL. */
+#define isc_refcount_decrement(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ LOCK(&(rp)->lock); \
+ REQUIRE((rp)->refs > 0); \
+ --((rp)->refs); \
+ if (_tmp != NULL) \
+ *_tmp = ((rp)->refs); \
+ UNLOCK(&(rp)->lock); \
+ } while (0)
+
+#endif /* ISC_PLATFORM_HAVEXADD */
+#else /* ISC_PLATFORM_USETHREADS */
+
+typedef struct isc_refcount {
+ int refs;
+} isc_refcount_t;
+
+#define isc_refcount_destroy(rp) (REQUIRE((rp)->refs == 0))
+#define isc_refcount_current(rp) ((unsigned int)((rp)->refs))
+
+#define isc_refcount_increment0(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ int _n = ++(rp)->refs; \
+ if (_tmp != NULL) \
+ *_tmp = _n; \
+ } while (0)
+
+#define isc_refcount_increment(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ int _n; \
+ REQUIRE((rp)->refs > 0); \
+ _n = ++(rp)->refs; \
+ if (_tmp != NULL) \
+ *_tmp = _n; \
+ } while (0)
+
+#define isc_refcount_decrement(rp, tp) \
+ do { \
+ unsigned int *_tmp = (unsigned int *)(tp); \
+ int _n; \
+ REQUIRE((rp)->refs > 0); \
+ _n = --(rp)->refs; \
+ if (_tmp != NULL) \
+ *_tmp = _n; \
+ } while (0)
+
+#endif /* ISC_PLATFORM_USETHREADS */
+
+isc_result_t
+isc_refcount_init(isc_refcount_t *ref, unsigned int n);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_REFCOUNT_H */
diff --git a/lib/isc/include/isc/region.h b/lib/isc/include/isc/region.h
new file mode 100644
index 000000000000..9b651fe4be64
--- /dev/null
+++ b/lib/isc/include/isc/region.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 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 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.19.18.2 2005/04/29 00:17:01 marka Exp $ */
+
+#ifndef ISC_REGION_H
+#define ISC_REGION_H 1
+
+/*! \file */
+
+#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/lib/isc/include/isc/resource.h b/lib/isc/include/isc/resource.h
new file mode 100644
index 000000000000..53b2a4e5a285
--- /dev/null
+++ b/lib/isc/include/isc/resource.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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: resource.h,v 1.5.18.2 2005/04/29 00:17:02 marka Exp $ */
+
+#ifndef ISC_RESOURCE_H
+#define ISC_RESOURCE_H 1
+
+/*! \file */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#define ISC_RESOURCE_UNLIMITED ((isc_resourcevalue_t)ISC_UINT64_MAX)
+
+ISC_LANG_BEGINDECLS
+
+isc_result_t
+isc_resource_setlimit(isc_resource_t resource, isc_resourcevalue_t value);
+/*%<
+ * Set the maximum limit for a system resource.
+ *
+ * Notes:
+ *\li If 'value' exceeds the maximum possible on the operating system,
+ * it is silently limited to that maximum -- or to "infinity", if
+ * the operating system has that concept. #ISC_RESOURCE_UNLIMITED
+ * can be used to explicitly ask for the maximum.
+ *
+ * Requires:
+ *\li 'resource' is a valid member of the isc_resource_t enumeration.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS.
+ *\li #ISC_R_NOPERM The calling process did not have adequate permission
+ * to change the resource limit.
+ */
+
+isc_result_t
+isc_resource_getlimit(isc_resource_t resource, isc_resourcevalue_t *value);
+/*%<
+ * Get the maximum limit for a system resource.
+ *
+ * Notes:
+ *\li 'value' is set to the maximum limit.
+ *
+ *\li #ISC_RESOURCE_UNLIMITED is the maximum value of isc_resourcevalue_t.
+ *
+ *\li On many (all?) Unix systems, RLIM_INFINITY is a valid value that is
+ * significantly less than #ISC_RESOURCE_UNLIMITED, but which in practice
+ * behaves the same.
+ *
+ *\li The current ISC libdns configuration file parser assigns a value
+ * of ISC_UINT32_MAX for a size_spec of "unlimited" and ISC_UNIT32_MAX - 1
+ * for "default", the latter of which is supposed to represent "the
+ * limit that was in force when the server started". Since these are
+ * valid values in the middle of the range of isc_resourcevalue_t,
+ * there is the possibility for confusion over what exactly those
+ * particular values are supposed to represent in a particular context --
+ * discrete integral values or generalized concepts.
+ *
+ * Requires:
+ *\li 'resource' is a valid member of the isc_resource_t enumeration.
+ *
+ * Returns:
+ *\li #ISC_R_SUCCESS Success.
+ *\li #ISC_R_NOTIMPLEMENTED 'resource' is not a type known by the OS.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RESOURCE_H */
+
diff --git a/lib/isc/include/isc/result.h b/lib/isc/include/isc/result.h
new file mode 100644
index 000000000000..0de3493fc553
--- /dev/null
+++ b/lib/isc/include/isc/result.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 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 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: result.h,v 1.62.18.4 2005/06/22 22:05:49 marka Exp $ */
+
+#ifndef ISC_RESULT_H
+#define ISC_RESULT_H 1
+
+#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_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 */
+
+/*% Not a result code: the number of results. */
+#define ISC_R_NRESULTS 60
+
+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/lib/isc/include/isc/resultclass.h b/lib/isc/include/isc/resultclass.h
new file mode 100644
index 000000000000..5e20800055ad
--- /dev/null
+++ b/lib/isc/include/isc/resultclass.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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.12.18.2 2005/04/29 00:17:02 marka Exp $ */
+
+#ifndef ISC_RESULTCLASS_H
+#define ISC_RESULTCLASS_H 1
+
+
+/*! \file
+ * \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)
+
+
+#endif /* ISC_RESULTCLASS_H */
diff --git a/lib/isc/include/isc/rwlock.h b/lib/isc/include/isc/rwlock.h
new file mode 100644
index 000000000000..404f93c43048
--- /dev/null
+++ b/lib/isc/include/isc/rwlock.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 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 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: rwlock.h,v 1.21.18.3 2005/06/04 06:23:44 jinmei Exp $ */
+
+#ifndef ISC_RWLOCK_H
+#define ISC_RWLOCK_H 1
+
+/*! \file */
+
+#include <isc/condition.h>
+#include <isc/lang.h>
+#include <isc/platform.h>
+#include <isc/types.h>
+
+ISC_LANG_BEGINDECLS
+
+typedef enum {
+ isc_rwlocktype_none = 0,
+ isc_rwlocktype_read,
+ isc_rwlocktype_write
+} isc_rwlocktype_t;
+
+#ifdef ISC_PLATFORM_USETHREADS
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+#define ISC_RWLOCK_USEATOMIC 1
+#endif
+
+struct isc_rwlock {
+ /* Unlocked. */
+ unsigned int magic;
+ isc_mutex_t lock;
+
+#if defined(ISC_PLATFORM_HAVEXADD) && defined(ISC_PLATFORM_HAVECMPXCHG)
+ /*
+ * When some atomic instructions with hardware assistance are
+ * available, rwlock will use those so that concurrent readers do not
+ * interfere with each other through mutex as long as no writers
+ * appear, massively reducing the lock overhead in the typical case.
+ *
+ * The basic algorithm of this approach is the "simple
+ * writer-preference lock" shown in the following URL:
+ * http://www.cs.rochester.edu/u/scott/synchronization/pseudocode/rw.html
+ * but our implementation does not rely on the spin lock unlike the
+ * original algorithm to be more portable as a user space application.
+ */
+
+ /* Read or modified atomically. */
+ isc_int32_t write_requests;
+ isc_int32_t write_completions;
+ isc_int32_t cnt_and_flag;
+
+ /* Locked by lock. */
+ isc_condition_t readable;
+ isc_condition_t writeable;
+ unsigned int readers_waiting;
+
+ /* Locked by rwlock itself. */
+ unsigned int write_granted;
+
+ /* Unlocked. */
+ unsigned int write_quota;
+
+#else /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
+
+ /*%< Locked by lock. */
+ isc_condition_t readable;
+ isc_condition_t writeable;
+ isc_rwlocktype_t type;
+
+ /*% The number of threads that have the lock. */
+ unsigned int active;
+
+ /*%
+ * The number of lock grants made since the lock was last switched
+ * from reading to writing or vice versa; used in determining
+ * when the quota is reached and it is time to switch.
+ */
+ unsigned int granted;
+
+ unsigned int readers_waiting;
+ unsigned int writers_waiting;
+ unsigned int read_quota;
+ unsigned int write_quota;
+ isc_rwlocktype_t original;
+#endif /* ISC_PLATFORM_HAVEXADD && ISC_PLATFORM_HAVECMPXCHG */
+};
+#else /* ISC_PLATFORM_USETHREADS */
+struct isc_rwlock {
+ unsigned int magic;
+ isc_rwlocktype_t type;
+ unsigned int active;
+};
+#endif /* ISC_PLATFORM_USETHREADS */
+
+
+isc_result_t
+isc_rwlock_init(isc_rwlock_t *rwl, unsigned int read_quota,
+ unsigned int write_quota);
+
+isc_result_t
+isc_rwlock_lock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
+
+isc_result_t
+isc_rwlock_trylock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
+
+isc_result_t
+isc_rwlock_unlock(isc_rwlock_t *rwl, isc_rwlocktype_t type);
+
+isc_result_t
+isc_rwlock_tryupgrade(isc_rwlock_t *rwl);
+
+void
+isc_rwlock_downgrade(isc_rwlock_t *rwl);
+
+void
+isc_rwlock_destroy(isc_rwlock_t *rwl);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_RWLOCK_H */
diff --git a/lib/isc/include/isc/serial.h b/lib/isc/include/isc/serial.h
new file mode 100644
index 000000000000..86d9b2f14d25
--- /dev/null
+++ b/lib/isc/include/isc/serial.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: serial.h,v 1.10.18.2 2005/04/29 00:17:02 marka Exp $ */
+
+#ifndef ISC_SERIAL_H
+#define ISC_SERIAL_H 1
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*! \file
+ * \brief Implement 32 bit serial space arithmetic comparision functions.
+ * Note: Undefined results are returned as ISC_FALSE.
+ */
+
+/***
+ *** Functions
+ ***/
+
+ISC_LANG_BEGINDECLS
+
+isc_boolean_t
+isc_serial_lt(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' < 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_gt(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' > 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_le(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' <= 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_ge(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' >= 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_eq(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' == 'b' otherwise false.
+ */
+
+isc_boolean_t
+isc_serial_ne(isc_uint32_t a, isc_uint32_t b);
+/*%<
+ * Return true if 'a' != 'b' otherwise false.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SERIAL_H */
diff --git a/lib/isc/include/isc/sha1.h b/lib/isc/include/isc/sha1.h
new file mode 100644
index 000000000000..bb22f06314d9
--- /dev/null
+++ b/lib/isc/include/isc/sha1.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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.9.18.5 2006/08/16 03:18:14 marka Exp $ */
+
+/* $NetBSD: sha1.h,v 1.2 1998/05/29 22:55:44 thorpej Exp $ */
+
+/*! \file
+ * \brief SHA-1 in C
+ * \author By Steve Reid <steve@edmweb.com>
+ * \note 100% Public Domain
+ */
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+#define ISC_SHA1_DIGESTLENGTH 20U
+#define ISC_SHA1_BLOCK_LENGTH 64U
+
+typedef struct {
+ isc_uint32_t state[5];
+ isc_uint32_t count[2];
+ unsigned char buffer[ISC_SHA1_BLOCK_LENGTH];
+} isc_sha1_t;
+
+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/lib/isc/include/isc/sha2.h b/lib/isc/include/isc/sha2.h
new file mode 100644
index 000000000000..e54c62060042
--- /dev/null
+++ b/lib/isc/include/isc/sha2.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2005, 2006 Internet Systems Consortium, Inc. ("ISC")
+ *
+ * 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 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: sha2.h,v 1.2.2.6 2006/08/16 03:18:14 marka Exp $ */
+
+/* $FreeBSD$ */
+/* $KAME: sha2.h,v 1.3 2001/03/12 08:27:48 itojun Exp $ */
+
+/*
+ * sha2.h
+ *
+ * Version 1.0.0beta1
+ *
+ * Written by Aaron D. Gifford <me@aarongifford.com>
+ *
+ * Copyright 2000 Aaron D. Gifford. 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. Neither the name of the copyright holder nor the names of contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTOR(S) ``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 AUTHOR(S) OR CONTRIBUTOR(S) 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.
+ *
+ */
+
+#ifndef ISC_SHA2_H
+#define ISC_SHA2_H
+
+#include <isc/lang.h>
+#include <isc/types.h>
+
+/*** SHA-224/256/384/512 Various Length Definitions ***********************/
+
+#define ISC_SHA224_BLOCK_LENGTH 64U
+#define ISC_SHA224_DIGESTLENGTH 28U
+#define ISC_SHA224_DIGESTSTRINGLENGTH (ISC_SHA224_DIGESTLENGTH * 2 + 1)
+#define ISC_SHA256_BLOCK_LENGTH 64U
+#define ISC_SHA256_DIGESTLENGTH 32U
+#define ISC_SHA256_DIGESTSTRINGLENGTH (ISC_SHA256_DIGESTLENGTH * 2 + 1)
+#define ISC_SHA384_BLOCK_LENGTH 128
+#define ISC_SHA384_DIGESTLENGTH 48U
+#define ISC_SHA384_DIGESTSTRINGLENGTH (ISC_SHA384_DIGESTLENGTH * 2 + 1)
+#define ISC_SHA512_BLOCK_LENGTH 128U
+#define ISC_SHA512_DIGESTLENGTH 64U
+#define ISC_SHA512_DIGESTSTRINGLENGTH (ISC_SHA512_DIGESTLENGTH * 2 + 1)
+
+
+ISC_LANG_BEGINDECLS
+
+/*** SHA-256/384/512 Context Structures *******************************/
+
+/*
+ * Keep buffer immediately after bitcount to preserve alignment.
+ */
+typedef struct {
+ isc_uint32_t state[8];
+ isc_uint64_t bitcount;
+ isc_uint8_t buffer[ISC_SHA256_BLOCK_LENGTH];
+} isc_sha256_t;
+
+/*
+ * Keep buffer immediately after bitcount to preserve alignment.
+ */
+typedef struct {
+ isc_uint64_t state[8];
+ isc_uint64_t bitcount[2];
+ isc_uint8_t buffer[ISC_SHA512_BLOCK_LENGTH];
+} isc_sha512_t;
+
+typedef isc_sha256_t isc_sha224_t;
+typedef isc_sha512_t isc_sha384_t;
+
+/*** SHA-224/256/384/512 Function Prototypes ******************************/
+
+void isc_sha224_init (isc_sha224_t *);
+void isc_sha224_update (isc_sha224_t *, const isc_uint8_t *, size_t);
+void isc_sha224_final (isc_uint8_t[ISC_SHA224_DIGESTLENGTH], isc_sha224_t *);
+char *isc_sha224_end (isc_sha224_t *, char[ISC_SHA224_DIGESTSTRINGLENGTH]);
+char *isc_sha224_data (const isc_uint8_t *, size_t, char[ISC_SHA224_DIGESTSTRINGLENGTH]);
+
+void isc_sha256_init (isc_sha256_t *);
+void isc_sha256_update (isc_sha256_t *, const isc_uint8_t *, size_t);
+void isc_sha256_final (isc_uint8_t[ISC_SHA256_DIGESTLENGTH], isc_sha256_t *);
+char *isc_sha256_end (isc_sha256_t *, char[ISC_SHA256_DIGESTSTRINGLENGTH]);
+char *isc_sha256_data (const isc_uint8_t *, size_t, char[ISC_SHA256_DIGESTSTRINGLENGTH]);
+
+void isc_sha384_init (isc_sha384_t *);
+void isc_sha384_update (isc_sha384_t *, const isc_uint8_t *, size_t);
+void isc_sha384_final (isc_uint8_t[ISC_SHA384_DIGESTLENGTH], isc_sha384_t *);
+char *isc_sha384_end (isc_sha384_t *, char[ISC_SHA384_DIGESTSTRINGLENGTH]);
+char *isc_sha384_data (const isc_uint8_t *, size_t, char[ISC_SHA384_DIGESTSTRINGLENGTH]);
+
+void isc_sha512_init (isc_sha512_t *);
+void isc_sha512_update (isc_sha512_t *, const isc_uint8_t *, size_t);
+void isc_sha512_final (isc_uint8_t[ISC_SHA512_DIGESTLENGTH], isc_sha512_t *);
+char *isc_sha512_end (isc_sha512_t *, char[ISC_SHA512_DIGESTSTRINGLENGTH]);
+char *isc_sha512_data (const isc_uint8_t *, size_t, char[ISC_SHA512_DIGESTSTRINGLENGTH]);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SHA2_H */
diff --git a/lib/isc/include/isc/sockaddr.h b/lib/isc/include/isc/sockaddr.h
new file mode 100644
index 000000000000..83412d2db4b1
--- /dev/null
+++ b/lib/isc/include/isc/sockaddr.h
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2003 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 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.42.18.8 2006/03/02 00:37:22 marka Exp $ */
+
+#ifndef ISC_SOCKADDR_H
+#define ISC_SOCKADDR_H 1
+
+/*! \file */
+
+#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.
+ */
+
+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 addresss.
+ */
+
+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/lib/isc/include/isc/socket.h b/lib/isc/include/isc/socket.h
new file mode 100644
index 000000000000..ccc49f53ca39
--- /dev/null
+++ b/lib/isc/include/isc/socket.h
@@ -0,0 +1,752 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 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 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: socket.h,v 1.57.18.6 2006/06/07 00:29:45 marka Exp $ */
+
+#ifndef ISC_SOCKET_H
+#define ISC_SOCKET_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \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>
+
+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
+
+/***
+ *** 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_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 */
+/*@}*/
+
+/***
+ *** 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_create(isc_socketmgr_t *manager,
+ int pf,
+ isc_sockettype_t type,
+ isc_socket_t **socketp);
+/*%<
+ * Create a new 'type' socket managed by 'manager'.
+ *
+ * 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
+ *
+ * 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
+ */
+
+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_bind(isc_socket_t *sock, isc_sockaddr_t *addressp);
+/*%<
+ * 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_create(isc_mem_t *mctx, isc_socketmgr_t **managerp);
+/*%<
+ * Create a socket manager.
+ *
+ * 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.
+ *
+ * Ensures:
+ *
+ *\li '*managerp' is a valid isc_socketmgr_t.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ */
+
+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 filesytem
+ * permissions on the socket.
+ *
+ * Requires:
+ * \li 'sockaddr' to be a valid UNIX domain sockaddr.
+ *
+ * Returns:
+ * \li #ISC_R_SUCCESS
+ * \li #ISC_R_FAILURE
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SOCKET_H */
diff --git a/lib/isc/include/isc/stdio.h b/lib/isc/include/isc/stdio.h
new file mode 100644
index 000000000000..e3bf0cd3ecab
--- /dev/null
+++ b/lib/isc/include/isc/stdio.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2000, 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 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.7.18.2 2005/04/29 00:17:03 marka Exp $ */
+
+#ifndef ISC_STDIO_H
+#define ISC_STDIO_H 1
+
+/*! \file */
+
+/*%
+ * 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/lib/isc/include/isc/stdlib.h b/lib/isc/include/isc/stdlib.h
new file mode 100644
index 000000000000..0e2c6977483e
--- /dev/null
+++ b/lib/isc/include/isc/stdlib.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2003 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 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: stdlib.h,v 1.2.18.2 2005/04/29 00:17:03 marka Exp $ */
+
+#ifndef ISC_STDLIB_H
+#define ISC_STDLIB_H 1
+
+/*! \file */
+
+#include <stdlib.h>
+
+#include <isc/lang.h>
+#include <isc/platform.h>
+
+#ifdef ISC_PLATFORM_NEEDSTRTOUL
+#define strtoul isc_strtoul
+#endif
+
+ISC_LANG_BEGINDECLS
+
+unsigned long isc_strtoul(const char *, char **, int);
+
+ISC_LANG_ENDDECLS
+
+#endif
diff --git a/lib/isc/include/isc/string.h b/lib/isc/include/isc/string.h
new file mode 100644
index 000000000000..bda71f46c52b
--- /dev/null
+++ b/lib/isc/include/isc/string.h
@@ -0,0 +1,231 @@
+/*
+ * 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: string.h,v 1.12.18.6 2007/09/13 05:04:01 each Exp $ */
+
+#ifndef ISC_STRING_H
+#define ISC_STRING_H 1
+
+/*! \file */
+
+#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
+ *
+ */
+
+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/lib/isc/include/isc/symtab.h b/lib/isc/include/isc/symtab.h
new file mode 100644
index 000000000000..94ea173c18ac
--- /dev/null
+++ b/lib/isc/include/isc/symtab.h
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2004-2006 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1996-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 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: symtab.h,v 1.17.18.4 2006/03/02 00:37:22 marka Exp $ */
+
+#ifndef ISC_SYMTAB_H
+#define ISC_SYMTAB_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \brief Provides a simple memory-based symbol table.
+ *
+ * Keys are C strings, and key comparisons are case-insenstive. A type may
+ * be specified when looking up, defining, or undefining. A type value of
+ * 0 means "match any type"; any other value will only match the given
+ * type.
+ *
+ * It's possible that a client will attempt to define a <key, type, value>
+ * tuple when a tuple with the given key and type already exists in the table.
+ * What to do in this case is specified by the client. Possible policies are:
+ *
+ *\li #isc_symexists_reject Disallow the define, returning #ISC_R_EXISTS
+ *\li #isc_symexists_replace Replace the old value with the new. The
+ * undefine action (if provided) will be called
+ * with the old <key, type, value> tuple.
+ *\li #isc_symexists_add Add the new tuple, leaving the old tuple in
+ * the table. Subsequent lookups will retrieve
+ * the most-recently-defined tuple.
+ *
+ * A lookup of a key using type 0 will return the most-recently defined
+ * symbol with that key. An undefine of a key using type 0 will undefine the
+ * most-recently defined symbol with that key. Trying to define a key with
+ * type 0 is illegal.
+ *
+ * The symbol table library does not make a copy the key field, so the
+ * caller must ensure that any key it passes to isc_symtab_define() will not
+ * change until it calls isc_symtab_undefine() or isc_symtab_destroy().
+ *
+ * A user-specified action will be called (if provided) when a symbol is
+ * undefined. It can be used to free memory associated with keys and/or
+ * values.
+ *
+ * \li MP:
+ * The callers of this module must ensure any required synchronization.
+ *
+ * \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>
+
+/*
+ *** Symbol Tables.
+ ***/
+/*% Symbol table value. */
+typedef union isc_symvalue {
+ void * as_pointer;
+ const void * as_cpointer;
+ int as_integer;
+ unsigned int as_uinteger;
+} isc_symvalue_t;
+
+typedef void (*isc_symtabaction_t)(char *key, unsigned int type,
+ isc_symvalue_t value, void *userarg);
+/*% Symbol table exists. */
+typedef enum {
+ isc_symexists_reject = 0, /*%< Disallow the define */
+ isc_symexists_replace = 1, /*%< Replace the old value with the new */
+ isc_symexists_add = 2 /*%< Add the new tuple */
+} isc_symexists_t;
+
+ISC_LANG_BEGINDECLS
+
+/*% Create a symbol table. */
+isc_result_t
+isc_symtab_create(isc_mem_t *mctx, unsigned int size,
+ isc_symtabaction_t undefine_action, void *undefine_arg,
+ isc_boolean_t case_sensitive, isc_symtab_t **symtabp);
+
+/*% Destroy a symbol table. */
+void
+isc_symtab_destroy(isc_symtab_t **symtabp);
+
+/*% Lookup a symbol table. */
+isc_result_t
+isc_symtab_lookup(isc_symtab_t *symtab, const char *key, unsigned int type,
+ isc_symvalue_t *value);
+
+/*% Define a symbol table. */
+isc_result_t
+isc_symtab_define(isc_symtab_t *symtab, const char *key, unsigned int type,
+ isc_symvalue_t value, isc_symexists_t exists_policy);
+
+/*% Undefine a symbol table. */
+isc_result_t
+isc_symtab_undefine(isc_symtab_t *symtab, const char *key, unsigned int type);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_SYMTAB_H */
diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h
new file mode 100644
index 000000000000..f7d237c29ef3
--- /dev/null
+++ b/lib/isc/include/isc/task.h
@@ -0,0 +1,616 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2001, 2003 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 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: task.h,v 1.51.18.2 2005/04/29 00:17:03 marka Exp $ */
+
+#ifndef ISC_TASK_H
+#define ISC_TASK_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \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 cancelling 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>
+
+#define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0)
+#define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1)
+#define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535)
+
+/*****
+ ***** Tasks.
+ *****/
+
+ISC_LANG_BEGINDECLS
+
+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".
+ */
+
+/*****
+ ***** Task Manager.
+ *****/
+
+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.
+ *
+ * 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
+ *
+ * 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.
+ */
+
+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 signalling 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.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TASK_H */
diff --git a/lib/isc/include/isc/taskpool.h b/lib/isc/include/isc/taskpool.h
new file mode 100644
index 000000000000..6c97605926d0
--- /dev/null
+++ b/lib/isc/include/isc/taskpool.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * 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 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: taskpool.h,v 1.9.18.2 2005/04/29 00:17:04 marka Exp $ */
+
+#ifndef ISC_TASKPOOL_H
+#define ISC_TASKPOOL_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \brief A task pool is a mechanism for sharing a small number of tasks
+ * among a large number of objects such that each object is
+ * assigned a unique task, but each task may be shared by several
+ * objects.
+ *
+ * Task pools are used to let objects that can exist in large
+ * numbers (e.g., zones) use tasks for synchronization without
+ * the memory overhead and unfair scheduling competition that
+ * could result from creating a separate task for each object.
+ */
+
+
+/***
+ *** Imports.
+ ***/
+
+#include <isc/lang.h>
+#include <isc/task.h>
+
+ISC_LANG_BEGINDECLS
+
+/*****
+ ***** Types.
+ *****/
+
+typedef struct isc_taskpool isc_taskpool_t;
+
+/*****
+ ***** Functions.
+ *****/
+
+isc_result_t
+isc_taskpool_create(isc_taskmgr_t *tmgr, isc_mem_t *mctx,
+ unsigned int ntasks, unsigned int quantum,
+ isc_taskpool_t **poolp);
+/*%<
+ * Create a task pool of "ntasks" tasks, each with quantum
+ * "quantum".
+ *
+ * Requires:
+ *
+ *\li 'tmgr' is a valid task manager.
+ *
+ *\li 'mctx' is a valid memory context.
+ *
+ *\li poolp != NULL && *poolp == NULL
+ *
+ * Ensures:
+ *
+ *\li On success, '*taskp' points to the new task pool.
+ *
+ * Returns:
+ *
+ *\li #ISC_R_SUCCESS
+ *\li #ISC_R_NOMEMORY
+ *\li #ISC_R_UNEXPECTED
+ */
+
+void
+isc_taskpool_gettask(isc_taskpool_t *pool, unsigned int hash,
+ isc_task_t **targetp);
+/*%<
+ * Attach to the task corresponding to the hash value "hash".
+ */
+
+void
+isc_taskpool_destroy(isc_taskpool_t **poolp);
+/*%<
+ * Destroy a task pool. The tasks in the pool are detached but not
+ * shut down.
+ *
+ * Requires:
+ * \li '*poolp' is a valid task pool.
+ */
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TASKPOOL_H */
diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h
new file mode 100644
index 000000000000..1e139dda819d
--- /dev/null
+++ b/lib/isc/include/isc/timer.h
@@ -0,0 +1,342 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2002 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 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.31.18.3 2005/10/26 06:50:50 marka Exp $ */
+
+#ifndef ISC_TIMER_H
+#define ISC_TIMER_H 1
+
+/*****
+ ***** Module Info
+ *****/
+
+/*! \file
+ * \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>
+
+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_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 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_create(isc_mem_t *mctx, isc_timermgr_t **managerp);
+/*%<
+ * Create a timer manager.
+ *
+ * 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.
+ *
+ * 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);
+
+ISC_LANG_ENDDECLS
+
+#endif /* ISC_TIMER_H */
diff --git a/lib/isc/include/isc/types.h b/lib/isc/include/isc/types.h
new file mode 100644
index 000000000000..35a0be7ae262
--- /dev/null
+++ b/lib/isc/include/isc/types.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1999-2003 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 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: types.h,v 1.35.18.2 2005/04/29 00:17:04 marka Exp $ */
+
+#ifndef ISC_TYPES_H
+#define ISC_TYPES_H 1
+
+/*! \file
+ * \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_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_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_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_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 *);
+
+/*% 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/lib/isc/include/isc/util.h b/lib/isc/include/isc/util.h
new file mode 100644
index 000000000000..95fe4363c0a4
--- /dev/null
+++ b/lib/isc/include/isc/util.h
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-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 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: util.h,v 1.24.18.2 2005/04/29 00:17:04 marka Exp $ */
+
+#ifndef ISC_UTIL_H
+#define ISC_UTIL_H 1
+
+/*! \file 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)
+
+#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 static void isc__empty(void) { isc__empty(); }
+
+/*%
+ * 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/lib/isc/include/isc/version.h b/lib/isc/include/isc/version.h
new file mode 100644
index 000000000000..82d4617c59f2
--- /dev/null
+++ b/lib/isc/include/isc/version.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 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 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: version.h,v 1.3.18.2 2005/04/29 00:17:04 marka Exp $ */
+
+/*! \file */
+
+#include <isc/platform.h>
+
+LIBISC_EXTERNAL_DATA extern const char isc_version[];
+
+LIBISC_EXTERNAL_DATA extern const unsigned int isc_libinterface;
+LIBISC_EXTERNAL_DATA extern const unsigned int isc_librevision;
+LIBISC_EXTERNAL_DATA extern const unsigned int isc_libage;
diff --git a/lib/isc/inet_aton.c b/lib/isc/inet_aton.c
new file mode 100644
index 000000000000..160252109c52
--- /dev/null
+++ b/lib/isc/inet_aton.c
@@ -0,0 +1,196 @@
+/*
+ * Portions Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (C) 1996-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 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.
+ */
+
+/*
+ * Copyright (c) 1983, 1990, 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.
+ */
+
+/*
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ *
+ * 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, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION 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 sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
+static char rcsid[] = "$Id: inet_aton.c,v 1.17.18.2 2005/04/29 00:16:46 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <config.h>
+
+#include <ctype.h>
+#include <stddef.h> /* Required for NULL. */
+
+#include <isc/types.h>
+#include <isc/net.h>
+
+/*%
+ * Check whether "cp" is a valid ascii representation
+ * of an Internet address and convert to a binary address.
+ * Returns 1 if the address is valid, 0 if not.
+ * This replaces inet_addr, the return value from which
+ * cannot distinguish between failure and a local broadcast address.
+ */
+int
+isc_net_aton(const char *cp, struct in_addr *addr) {
+ unsigned long val;
+ int base, n;
+ unsigned char c;
+ isc_uint8_t parts[4];
+ isc_uint8_t *pp = parts;
+ int digit;
+
+ c = *cp;
+ for (;;) {
+ /*
+ * Collect number up to ``.''.
+ * Values are specified as for C:
+ * 0x=hex, 0=octal, isdigit=decimal.
+ */
+ if (!isdigit(c & 0xff))
+ return (0);
+ val = 0; base = 10; digit = 0;
+ if (c == '0') {
+ c = *++cp;
+ if (c == 'x' || c == 'X')
+ base = 16, c = *++cp;
+ else {
+ base = 8;
+ digit = 1;
+ }
+ }
+ for (;;) {
+ /*
+ * isascii() is valid for all integer values, and
+ * when it is true, c is known to be in scope
+ * for isdigit(). No cast necessary. Similar
+ * comment applies for later ctype uses.
+ */
+ if (isascii(c) && isdigit(c)) {
+ if (base == 8 && (c == '8' || c == '9'))
+ return (0);
+ val = (val * base) + (c - '0');
+ c = *++cp;
+ digit = 1;
+ } else if (base == 16 && isascii(c) && isxdigit(c)) {
+ val = (val << 4) |
+ (c + 10 - (islower(c) ? 'a' : 'A'));
+ c = *++cp;
+ digit = 1;
+ } else
+ break;
+ }
+ if (c == '.') {
+ /*
+ * Internet format:
+ * a.b.c.d
+ * a.b.c (with c treated as 16 bits)
+ * a.b (with b treated as 24 bits)
+ */
+ if (pp >= parts + 3 || val > 0xff)
+ return (0);
+ *pp++ = (isc_uint8_t)val;
+ c = *++cp;
+ } else
+ break;
+ }
+ /*
+ * Check for trailing characters.
+ */
+ if (c != '\0' && (!isascii(c) || !isspace(c)))
+ return (0);
+ /*
+ * Did we get a valid digit?
+ */
+ if (!digit)
+ return (0);
+ /*
+ * Concoct the address according to
+ * the number of parts specified.
+ */
+ n = pp - parts + 1;
+ switch (n) {
+ case 1: /* a -- 32 bits */
+ break;
+
+ case 2: /* a.b -- 8.24 bits */
+ if (val > 0xffffff)
+ return (0);
+ val |= parts[0] << 24;
+ break;
+
+ case 3: /* a.b.c -- 8.8.16 bits */
+ if (val > 0xffff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16);
+ break;
+
+ case 4: /* a.b.c.d -- 8.8.8.8 bits */
+ if (val > 0xff)
+ return (0);
+ val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+ break;
+ }
+ if (addr != NULL)
+ addr->s_addr = htonl(val);
+
+ return (1);
+}
diff --git a/lib/isc/inet_ntop.c b/lib/isc/inet_ntop.c
new file mode 100644
index 000000000000..c0d1161d663b
--- /dev/null
+++ b/lib/isc/inet_ntop.c
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1996-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 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.14.18.3 2005/04/29 00:16:46 marka 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
+
+/*! 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")];
+
+ if ((size_t)sprintf(tmp, fmt, src[0], src[1], src[2], src[3]) >= size)
+ {
+ errno = ENOSPC;
+ return (NULL);
+ }
+ strcpy(dst, tmp);
+
+ 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;
+ 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 == 5 && words[5] == 0xffff))) {
+ if (!inet_ntop4(src+12, tp,
+ sizeof(tmp) - (tp - tmp)))
+ return (NULL);
+ tp += strlen(tp);
+ break;
+ }
+ tp += sprintf(tp, "%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);
+ }
+ strcpy(dst, tmp);
+ return (dst);
+}
+#endif /* AF_INET6 */
diff --git a/lib/isc/inet_pton.c b/lib/isc/inet_pton.c
new file mode 100644
index 000000000000..a537e9c59656
--- /dev/null
+++ b/lib/isc/inet_pton.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1996-2003 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 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.13.18.4 2005/04/29 00:16:46 marka 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);
+
+/*%
+ * 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) {
+ unsigned int new = *tp * 10 + (pch - digits);
+
+ if (saw_digit && *tp == 0)
+ return (0);
+ if (new > 255)
+ return (0);
+ *tp = new;
+ 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 (tp + NS_INT16SZ > endp)
+ return (0);
+ *tp++ = (unsigned char) (val >> 8) & 0xff;
+ *tp++ = (unsigned char) val & 0xff;
+ seen_xdigits = 0;
+ val = 0;
+ continue;
+ }
+ if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+ inet_pton4(curtok, tp) > 0) {
+ tp += NS_INADDRSZ;
+ seen_xdigits = 0;
+ break; /* '\0' was seen by inet_pton4(). */
+ }
+ return (0);
+ }
+ if (seen_xdigits) {
+ if (tp + NS_INT16SZ > endp)
+ 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 int n = tp - colonp;
+ int i;
+
+ if (tp == endp)
+ return (0);
+ for (i = 1; 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/lib/isc/lex.c b/lib/isc/lex.c
new file mode 100644
index 000000000000..2e4e48ae3343
--- /dev/null
+++ b/lib/isc/lex.c
@@ -0,0 +1,963 @@
+/*
+ * Copyright (C) 2004, 2005 Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 1998-2003 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 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: lex.c,v 1.78.18.5 2005/11/30 03:44:39 marka Exp $ */
+
+/*! \file */
+
+#include <config.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <isc/buffer.h>
+#include <isc/file.h>
+#include <isc/lex.h>
+#include <isc/mem.h>
+#include <isc/msgs.h>
+#include <isc/parseint.h>
+#include <isc/print.h>
+#include <isc/stdio.h>
+#include <isc/string.h>
+#include <isc/util.h>
+
+typedef struct inputsource {
+ isc_result_t result;
+ isc_boolean_t is_file;
+ isc_boolean_t need_close;
+ isc_boolean_t at_eof;
+ isc_buffer_t * pushback;
+ unsigned int ignored;
+ void * input;
+ char * name;
+ unsigned long line;
+ unsigned long saved_line;
+ ISC_LINK(struct inputsource) link;
+} inputsource;
+
+#define LEX_MAGIC ISC_MAGIC('L', 'e', 'x', '!')
+#define VALID_LEX(l) ISC_MAGIC_VALID(l, LEX_MAGIC)
+
+struct isc_lex {
+ /* Unlocked. */
+ unsigned int magic;
+ isc_mem_t * mctx;
+ size_t max_token;
+ char * data;
+ unsigned int comments;
+ isc_boolean_t comment_ok;
+ isc_boolean_t last_was_eol;
+ unsigned int paren_count;
+ unsigned int saved_paren_count;
+ isc_lexspecials_t specials;
+ LIST(struct inputsource) sources;
+};
+
+static inline isc_result_t
+grow_data(isc_lex_t *lex, size_t *remainingp, char **currp, char **prevp) {
+ char *new;
+
+ new = isc_mem_get(lex->mctx, lex->max_token * 2 + 1);
+ if (new == NULL)
+ return (ISC_R_NOMEMORY);
+ memcpy(new, lex->data, lex->max_token + 1);
+ *currp = new + (*currp - lex->data);
+ if (*prevp != NULL)
+ *prevp = new + (*prevp - lex->data);
+ isc_mem_put(lex->mctx, lex->data, lex->max_token + 1);
+ lex->data = new;
+ *remainingp += lex->max_token;
+ lex->max_token *= 2;
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_lex_create(isc_mem_t *mctx, size_t max_token, isc_lex_t **lexp) {
+ isc_lex_t *lex;
+
+ /*
+ * Create a lexer.
+ */
+
+ REQUIRE(lexp != NULL && *lexp == NULL);
+ REQUIRE(max_token > 0U);
+
+ lex = isc_mem_get(mctx, sizeof(*lex));
+ if (lex == NULL)
+ return (ISC_R_NOMEMORY);
+ lex->data = isc_mem_get(mctx, max_token + 1);
+ if (lex->data == NULL) {
+ isc_mem_put(mctx, lex, sizeof(*lex));
+ return (ISC_R_NOMEMORY);
+ }
+ lex->mctx = mctx;
+ lex->max_token = max_token;
+ lex->comments = 0;
+ lex->comment_ok = ISC_TRUE;
+ lex->last_was_eol = ISC_TRUE;
+ lex->paren_count = 0;
+ lex->saved_paren_count = 0;
+ memset(lex->specials, 0, 256);
+ INIT_LIST(lex->sources);
+ lex->magic = LEX_MAGIC;
+
+ *lexp = lex;
+
+ return (ISC_R_SUCCESS);
+}
+
+void
+isc_lex_destroy(isc_lex_t **lexp) {
+ isc_lex_t *lex;
+
+ /*
+ * Destroy the lexer.
+ */
+
+ REQUIRE(lexp != NULL);
+ lex = *lexp;
+ REQUIRE(VALID_LEX(lex));
+
+ while (!EMPTY(lex->sources))
+ RUNTIME_CHECK(isc_lex_close(lex) == ISC_R_SUCCESS);
+ if (lex->data != NULL)
+ isc_mem_put(lex->mctx, lex->data, lex->max_token + 1);
+ lex->magic = 0;
+ isc_mem_put(lex->mctx, lex, sizeof(*lex));
+
+ *lexp = NULL;
+}
+
+unsigned int
+isc_lex_getcomments(isc_lex_t *lex) {
+ /*
+ * Return the current lexer commenting styles.
+ */
+
+ REQUIRE(VALID_LEX(lex));
+
+ return (lex->comments);
+}
+
+void
+isc_lex_setcomments(isc_lex_t *lex, unsigned int comments) {
+ /*
+ * Set allowed lexer commenting styles.
+ */
+
+ REQUIRE(VALID_LEX(lex));
+
+ lex->comments = comments;
+}
+
+void
+isc_lex_getspecials(isc_lex_t *lex, isc_lexspecials_t specials) {
+ /*
+ * Put the current list of specials into 'specials'.
+ */
+
+ REQUIRE(VALID_LEX(lex));
+
+ memcpy(specials, lex->specials, 256);
+}
+
+void
+isc_lex_setspecials(isc_lex_t *lex, isc_lexspecials_t specials) {
+ /*
+ * The characters in 'specials' are returned as tokens. Along with
+ * whitespace, they delimit strings and numbers.
+ */
+
+ REQUIRE(VALID_LEX(lex));
+
+ memcpy(lex->specials, specials, 256);
+}
+
+static inline isc_result_t
+new_source(isc_lex_t *lex, isc_boolean_t is_file, isc_boolean_t need_close,
+ void *input, const char *name)
+{
+ inputsource *source;
+ isc_result_t result;
+
+ source = isc_mem_get(lex->mctx, sizeof(*source));
+ if (source == NULL)
+ return (ISC_R_NOMEMORY);
+ source->result = ISC_R_SUCCESS;
+ source->is_file = is_file;
+ source->need_close = need_close;
+ source->at_eof = ISC_FALSE;
+ source->input = input;
+ source->name = isc_mem_strdup(lex->mctx, name);
+ if (source->name == NULL) {
+ isc_mem_put(lex->mctx, source, sizeof(*source));
+ return (ISC_R_NOMEMORY);
+ }
+ source->pushback = NULL;
+ result = isc_buffer_allocate(lex->mctx, &source->pushback,
+ lex->max_token);
+ if (result != ISC_R_SUCCESS) {
+ isc_mem_free(lex->mctx, source->name);
+ isc_mem_put(lex->mctx, source, sizeof(*source));
+ return (result);
+ }
+ source->ignored = 0;
+ source->line = 1;
+ ISC_LIST_INITANDPREPEND(lex->sources, source, link);
+
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_lex_openfile(isc_lex_t *lex, const char *filename) {
+ isc_result_t result;
+ FILE *stream = NULL;
+
+ /*
+ * Open 'filename' and make it the current input source for 'lex'.
+ */
+
+ REQUIRE(VALID_LEX(lex));
+
+ result = isc_stdio_open(filename, "r", &stream);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+
+ result = new_source(lex, ISC_TRUE, ISC_TRUE, stream, filename);
+ if (result != ISC_R_SUCCESS)
+ (void)fclose(stream);
+ return (result);
+}
+
+isc_result_t
+isc_lex_openstream(isc_lex_t *lex, FILE *stream) {
+ char name[128];
+
+ /*
+ * Make 'stream' the current input source for 'lex'.
+ */
+
+ REQUIRE(VALID_LEX(lex));
+
+ snprintf(name, sizeof(name), "stream-%p", stream);
+
+ return (new_source(lex, ISC_TRUE, ISC_FALSE, stream, name));
+}
+
+isc_result_t
+isc_lex_openbuffer(isc_lex_t *lex, isc_buffer_t *buffer) {
+ char name[128];
+
+ /*
+ * Make 'buffer' the current input source for 'lex'.
+ */
+
+ REQUIRE(VALID_LEX(lex));
+
+ snprintf(name, sizeof(name), "buffer-%p", buffer);
+
+ return (new_source(lex, ISC_FALSE, ISC_FALSE, buffer, name));
+}
+
+isc_result_t
+isc_lex_close(isc_lex_t *lex) {
+ inputsource *source;
+
+ /*
+ * Close the most recently opened object (i.e. file or buffer).
+ */
+
+ REQUIRE(VALID_LEX(lex));
+
+ source = HEAD(lex->sources);
+ if (source == NULL)
+ return (ISC_R_NOMORE);
+
+ ISC_LIST_UNLINK(lex->sources, source, link);
+ if (source->is_file) {
+ if (source->need_close)
+ (void)fclose((FILE *)(source->input));
+ }
+ isc_mem_free(lex->mctx, source->name);
+ isc_buffer_free(&source->pushback);
+ isc_mem_put(lex->mctx, source, sizeof(*source));
+
+ return (ISC_R_SUCCESS);
+}
+
+typedef enum {
+ lexstate_start,
+ lexstate_crlf,
+ lexstate_string,
+ lexstate_number,
+ lexstate_maybecomment,
+ lexstate_ccomment,
+ lexstate_ccommentend,
+ lexstate_eatline,
+ lexstate_qstring
+} lexstate;
+
+#define IWSEOL (ISC_LEXOPT_INITIALWS | ISC_LEXOPT_EOL)
+
+static void
+pushback(inputsource *source, int c) {
+ REQUIRE(source->pushback->current > 0);
+ if (c == EOF) {
+ source->at_eof = ISC_FALSE;
+ return;
+ }
+ source->pushback->current--;
+ if (c == '\n')
+ source->line--;
+}
+
+static isc_result_t
+pushandgrow(isc_lex_t *lex, inputsource *source, int c) {
+ if (isc_buffer_availablelength(source->pushback) == 0) {
+ isc_buffer_t *tbuf = NULL;
+ unsigned int oldlen;
+ isc_region_t used;
+ isc_result_t result;
+
+ oldlen = isc_buffer_length(source->pushback);
+ result = isc_buffer_allocate(lex->mctx, &tbuf, oldlen * 2);
+ if (result != ISC_R_SUCCESS)
+ return (result);
+ isc_buffer_usedregion(source->pushback, &used);
+ result = isc_buffer_copyregion(tbuf, &used);
+ INSIST(result == ISC_R_SUCCESS);
+ tbuf->current = source->pushback->current;
+ isc_buffer_free(&source->pushback);
+ source->pushback = tbuf;
+ }
+ isc_buffer_putuint8(source->pushback, (isc_uint8_t)c);
+ return (ISC_R_SUCCESS);
+}
+
+isc_result_t
+isc_lex_gettoken(isc_lex_t *lex, unsigned int options, isc_token_t *tokenp) {
+ inputsource *source;
+ int c;
+ isc_boolean_t done = ISC_FALSE;
+ isc_boolean_t no_comments = ISC_FALSE;
+ isc_boolean_t escaped = ISC_FALSE;
+ lexstate state = lexstate_start;
+ lexstate saved_state = lexstate_start;
+ isc_buffer_t *buffer;
+ FILE *stream;
+ char *curr, *prev;
+ size_t remaining;
+ isc_uint32_t as_ulong;
+ unsigned int saved_options;
+ isc_result_t result;
+
+ /*
+ * Get the next token.
+ */
+
+ REQUIRE(VALID_LEX(lex));
+ source = HEAD(lex->sources);
+ REQUIRE(tokenp != NULL);
+
+ if (source == NULL) {
+ if ((options & ISC_LEXOPT_NOMORE) != 0) {
+ tokenp->type = isc_tokentype_nomore;
+ return (ISC_R_SUCCESS);
+ }
+ return (ISC_R_NOMORE);
+ }
+
+ if (source->result != ISC_R_SUCCESS)
+ return (source->result);
+
+ lex->saved_paren_count = lex->paren_count;
+ source->saved_line = source->line;
+
+ if (isc_buffer_remaininglength(source->pushback) == 0 &&
+ source->at_eof)
+ {
+ if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
+ lex->paren_count != 0) {
+ lex->paren_count = 0;
+ return (ISC_R_UNBALANCED);
+ }
+ if ((options & ISC_LEXOPT_EOF) != 0) {
+ tokenp->type = isc_tokentype_eof;
+ return (ISC_R_SUCCESS);
+ }
+ return (ISC_R_EOF);
+ }
+
+ isc_buffer_compact(source->pushback);
+
+ saved_options = options;
+ if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 && lex->paren_count > 0)
+ options &= ~IWSEOL;
+
+ curr = lex->data;
+ *curr = '\0';
+
+ prev = NULL;
+ remaining = lex->max_token;
+
+#ifdef HAVE_FLOCKFILE
+ if (source->is_file)
+ flockfile(source->input);
+#endif
+
+ do {
+ if (isc_buffer_remaininglength(source->pushback) == 0) {
+ if (source->is_file) {
+ stream = source->input;
+
+#if defined(HAVE_FLOCKFILE) && defined(HAVE_GETCUNLOCKED)
+ c = getc_unlocked(stream);
+#else
+ c = getc(stream);
+#endif
+ if (c == EOF) {
+ if (ferror(stream)) {
+ source->result = ISC_R_IOERROR;
+ result = source->result;
+ goto done;
+ }
+ source->at_eof = ISC_TRUE;
+ }
+ } else {
+ buffer = source->input;
+
+ if (buffer->current == buffer->used) {
+ c = EOF;
+ source->at_eof = ISC_TRUE;
+ } else {
+ c = *((char *)buffer->base +
+ buffer->current);
+ buffer->current++;
+ }
+ }
+ if (c != EOF) {
+ source->result = pushandgrow(lex, source, c);
+ if (source->result != ISC_R_SUCCESS) {
+ result = source->result;
+ goto done;
+ }
+ }
+ }
+
+ if (!source->at_eof) {
+ if (state == lexstate_start)
+ /* Token has not started yet. */
+ source->ignored =
+ isc_buffer_consumedlength(source->pushback);
+ c = isc_buffer_getuint8(source->pushback);
+ } else {
+ c = EOF;
+ }
+
+ if (c == '\n')
+ source->line++;
+
+ if (lex->comment_ok && !no_comments) {
+ if (!escaped && c == ';' &&
+ ((lex->comments & ISC_LEXCOMMENT_DNSMASTERFILE)
+ != 0)) {
+ saved_state = state;
+ state = lexstate_eatline;
+ no_comments = ISC_TRUE;
+ continue;
+ } else if (c == '/' &&
+ (lex->comments &
+ (ISC_LEXCOMMENT_C|
+ ISC_LEXCOMMENT_CPLUSPLUS)) != 0) {
+ saved_state = state;
+ state = lexstate_maybecomment;
+ no_comments = ISC_TRUE;
+ continue;
+ } else if (c == '#' &&
+ ((lex->comments & ISC_LEXCOMMENT_SHELL)
+ != 0)) {
+ saved_state = state;
+ state = lexstate_eatline;
+ no_comments = ISC_TRUE;
+ continue;
+ }
+ }
+
+ no_read:
+ /* INSIST(c == EOF || (c >= 0 && c <= 255)); */
+ switch (state) {
+ case lexstate_start:
+ if (c == EOF) {
+ lex->last_was_eol = ISC_FALSE;
+ if ((options & ISC_LEXOPT_DNSMULTILINE) != 0 &&
+ lex->paren_count != 0) {
+ lex->paren_count = 0;
+ result = ISC_R_UNBALANCED;
+ goto done;
+ }
+ if ((options & ISC_LEXOPT_EOF) == 0) {
+ result = ISC_R_EOF;
+ goto done;
+ }
+ tokenp->type = isc_tokentype_eof;
+ done = ISC_TRUE;
+ } else if (c == ' ' || c == '\t') {
+ if (lex->last_was_eol &&
+ (options & ISC_LEXOPT_INITIALWS)
+ != 0) {
+ lex->last_was_eol = ISC_FALSE;
+ tokenp->type = isc_tokentype_initialws;
+ tokenp->value.as_char = c;
+ done = ISC_TRUE;
+ }
+ } else if (c == '\n') {
+ if ((options & ISC_LEXOPT_EOL) != 0) {
+ tokenp->type = isc_tokentype_eol;
+ done = ISC_TRUE;
+ }
+ lex->last_was_eol = ISC_TRUE;
+ } else if (c == '\r') {
+ if ((options & ISC_LEXOPT_EOL) != 0)
+ state = lexstate_crlf;
+ } else if (c == '"' &&
+ (options & ISC_LEXOPT_QSTRING) != 0) {
+ lex->last_was_eol = ISC_FALSE;
+ no_comments = ISC_TRUE;
+ state = lexstate_qstring;
+ } else if (lex->specials[c]) {
+ lex->last_was_eol = ISC_FALSE;
+ if ((c == '(' || c == ')') &&
+ (options & ISC_LEXOPT_DNSMULTILINE) != 0) {
+ if (c == '(') {
+ if (lex->paren_count == 0)
+ options &= ~IWSEOL;
+ lex->paren_count++;
+ } else {
+ if (lex->paren_count == 0) {
+ result = ISC_R_UNBALANCED;
+ goto done;
+ }
+ lex->paren_count--;
+ if (lex->paren_count == 0)
+ options =
+ saved_options;
+ }
+ continue;
+ }
+ tokenp->type = isc_tokentype_special;
+ tokenp->value.as_char = c;
+ done = ISC_TRUE;
+ } else if (isdigit((unsigned char)c) &&
+ (options & ISC_LEXOPT_NUMBER) != 0) {
+ lex->last_was_eol = ISC_FALSE;
+ if ((options & ISC_LEXOPT_OCTAL) != 0 &&
+ (c == '8' || c == '9'))
+ state = lexstate_string;
+ else
+ state = lexstate_number;
+ goto no_read;
+ } else {
+ lex->last_was_eol = ISC_FALSE;
+ state = lexstate_string;
+ goto no_read;
+ }
+ break;
+ case lexstate_crlf:
+ if (c != '\n')
+ pushback(source, c);
+ tokenp->type = isc_tokentype_eol;
+ done = ISC_TRUE;
+ lex->last_was_eol = ISC_TRUE;
+ break;
+ case lexstate_number:
+ if (c == EOF || !isdigit((unsigned char)c)) {
+ if (c == ' ' || c == '\t' || c == '\r' ||
+ c == '\n' || c == EOF ||
+ lex->specials[c]) {
+ int base;
+ if ((options & ISC_LEXOPT_OCTAL) != 0)
+ base = 8;
+ else if ((options & ISC_LEXOPT_CNUMBER) != 0)
+ base = 0;
+ else
+ base = 10;
+ pushback(source, c);
+
+ result = isc_parse_uint32(&as_ulong,
+ lex->data,
+ base);
+ if (result == ISC_R_SUCCESS) {
+ tokenp->type =
+ isc_tokentype_number;
+ tokenp->value.as_ulong =
+ as_ulong;
+ } else if (result == ISC_R_BADNUMBER) {
+ isc_tokenvalue_t *v;
+
+ tokenp->type =
+ isc_tokentype_string;
+ v = &(tokenp->value);
+ v->as_textregion.base =
+ lex->data;
+ v->as_textregion.length =
+ lex->max_token -
+ remaining;
+ } else
+ goto done;
+ done = ISC_TRUE;
+ continue;
+ } else if (!(options & ISC_LEXOPT