BIND: entirely purge BIND and related stuff from base
authorJan Lentfer <lentferj@df64devel.lan.net>
Mon, 8 Mar 2010 10:17:32 +0000 (11:17 +0100)
committerJan Lentfer <lentferj@atom.lan.net>
Thu, 6 May 2010 10:49:15 +0000 (12:49 +0200)
83 files changed:
lib/Makefile
lib/libbind/Makefile [deleted file]
lib/libbind/port_after.h [deleted file]
lib/libbind/port_before.h [deleted file]
lib/libbind9/Makefile [deleted file]
lib/libc/include/isc/eventlib.h [new file with mode: 0644]
lib/libc/include/isc/list.h [new file with mode: 0644]
lib/libc/include/resolv_mt.h [new file with mode: 0644]
lib/libc/inet/inet_addr.c [new file with mode: 0644]
lib/libc/inet/inet_cidr_ntop.c [new file with mode: 0644]
lib/libc/inet/inet_cidr_pton.c [new file with mode: 0644]
lib/libc/inet/inet_data.c [new file with mode: 0644]
lib/libc/inet/inet_lnaof.c [new file with mode: 0644]
lib/libc/inet/inet_makeaddr.c [new file with mode: 0644]
lib/libc/inet/inet_net_ntop.c [new file with mode: 0644]
lib/libc/inet/inet_net_pton.c [new file with mode: 0644]
lib/libc/inet/inet_neta.c [new file with mode: 0644]
lib/libc/inet/inet_netof.c [new file with mode: 0644]
lib/libc/inet/inet_network.c [new file with mode: 0644]
lib/libc/inet/inet_ntoa.c [new file with mode: 0644]
lib/libc/inet/inet_ntop.c [new file with mode: 0644]
lib/libc/inet/inet_pton.c [new file with mode: 0644]
lib/libc/inet/nsap_addr.c [new file with mode: 0644]
lib/libc/isc/ev_streams.c [new file with mode: 0644]
lib/libc/isc/ev_timers.c [new file with mode: 0644]
lib/libc/isc/eventlib_p.h [new file with mode: 0644]
lib/libc/nameser/ns_name.c [new file with mode: 0644]
lib/libc/nameser/ns_netint.c [new file with mode: 0644]
lib/libc/nameser/ns_parse.c [new file with mode: 0644]
lib/libc/nameser/ns_print.c [new file with mode: 0644]
lib/libc/nameser/ns_samedomain.c [new file with mode: 0644]
lib/libc/nameser/ns_ttl.c [new file with mode: 0644]
lib/libc/net/Makefile.inc
lib/libc/resolv/Makefile.inc
lib/libc/resolv/herror.c [new file with mode: 0644]
lib/libc/resolv/mtctxres.c [new file with mode: 0644]
lib/libc/resolv/res_comp.c [new file with mode: 0644]
lib/libc/resolv/res_data.c [new file with mode: 0644]
lib/libc/resolv/res_debug.c [new file with mode: 0644]
lib/libc/resolv/res_debug.h [new file with mode: 0644]
lib/libc/resolv/res_findzonecut.c [new file with mode: 0644]
lib/libc/resolv/res_init.c [new file with mode: 0644]
lib/libc/resolv/res_mkquery.c [new file with mode: 0644]
lib/libc/resolv/res_mkupdate.c [new file with mode: 0644]
lib/libc/resolv/res_mkupdate.h [new file with mode: 0644]
lib/libc/resolv/res_private.h [new file with mode: 0644]
lib/libc/resolv/res_query.c [new file with mode: 0644]
lib/libc/resolv/res_send.c [new file with mode: 0644]
lib/libc/resolv/res_sendsigned.c [new file with mode: 0644]
lib/libc/resolv/res_update.c [new file with mode: 0644]
lib/libc_rtld/Makefile
lib/libisc/Makefile [deleted file]
usr.bin/Makefile
usr.bin/dig/Makefile [deleted file]
usr.bin/dnssec-keygen/Makefile [deleted file]
usr.bin/dnssec-signzone/Makefile [deleted file]
usr.bin/host/Makefile [deleted file]
usr.sbin/Makefile
usr.sbin/named-checkconf/Makefile [deleted file]
usr.sbin/named-checkzone/Makefile [deleted file]
usr.sbin/named.reload/Makefile [deleted file]
usr.sbin/named.reload/named.reload.8 [deleted file]
usr.sbin/named.reload/named.reload.sh [deleted file]
usr.sbin/named.restart/Makefile [deleted file]
usr.sbin/named.restart/named.restart.8 [deleted file]
usr.sbin/named.restart/named.restart.sh [deleted file]
usr.sbin/named/Makefile [deleted file]
usr.sbin/named/Makefile.inc [deleted file]
usr.sbin/named/Makefile.maninc [deleted file]
usr.sbin/named/code.h [deleted file]
usr.sbin/named/config.h [deleted file]
usr.sbin/named/include/dns/enumclass.h [deleted file]
usr.sbin/named/include/dns/enumtype.h [deleted file]
usr.sbin/named/include/dns/rdatastruct.h [deleted file]
usr.sbin/named/include/isc/os.h [deleted file]
usr.sbin/named/include/isc/platform.h [deleted file]
usr.sbin/named/include/lwres/netdb.h [deleted file]
usr.sbin/named/include/lwres/platform.h [deleted file]
usr.sbin/named/include/named/os.h [deleted file]
usr.sbin/nslookup/Makefile [deleted file]
usr.sbin/nsupdate/Makefile [deleted file]
usr.sbin/rndc-confgen/Makefile [deleted file]
usr.sbin/rndc/Makefile [deleted file]

index 9de7f5c..fa7a7ad 100644 (file)
 SUBDIR=        csu \
        libbluetooth libcom_err libcrypt libm libmd libarchive \
        libncurses libradius librt libtacplus libutil libsbuf \
-       libalias libatm ${_libbind} ${_libbind9} libbz2 libc ${_libc_r} \
+       libalias libatm libbz2 libc ${_libc_r} \
        libcalendar libcam libcompat libdevinfo libdevstat libedit \
        libevent libexpat libfetch \
-       libftpio libipsec libipx libisc libkcore libkiconv libkinfo \
+       libftpio libipsec libipx libkcore libkiconv libkinfo \
        libkvm libmagic \
        ${_libmilter} ${_libncp} libnetgraph libopie libpam \
        libpcap libposix1e libsdp libthread_xu libpthread librpcsvc ${_libsm} \
@@ -40,11 +40,6 @@ SUBDIR+= compat/${MACHINE_ARCH}
 _libc_r=       libc_r
 .endif
 
-.if !defined(NO_BIND)
-_libbind=      libbind
-_libbind9=     libbind9
-.endif
-
 .if !defined(NO_SENDMAIL)
 _libmilter=    libmilter
 _libsm=                libsm
diff --git a/lib/libbind/Makefile b/lib/libbind/Makefile
deleted file mode 100644 (file)
index d23acb9..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-# $FreeBSD: src/lib/libbind/Makefile,v 1.5.2.2 2002/07/19 18:46:25 ru Exp $
-# $DragonFly: src/lib/libbind/Makefile,v 1.10 2007/02/15 20:28:49 victor Exp $
-
-BIND_DIR=${.CURDIR}/../../contrib/bind
-
-# note: lib/bind/include/isc/list.h must come before lib/isc/include/isc/list.h
-#
-CFLAGS+= -I${.CURDIR}/../../usr.sbin/named \
-       -I${.CURDIR}/../../usr.sbin/named/include \
-       -I${BIND_DIR}/lib/bind/include \
-       -DHAVE_MEMCHR
-
-.include "${.CURDIR}/../../usr.sbin/named/Makefile.inc"
-.include "${BIND_DIR}/lib/bind/api"
-
-LIB= bind
-WANT_IRS= for now
-
-# This may or may not work yet.  It's not compatible with the core
-# system components since it overrides the master.passwd handling etc.
-.if defined(WANT_IRS)
-.PATH: ${BIND_DIR}/lib/bind/irs
-
-SRCS+= dns.c dns_gr.c dns_ho.c dns_nw.c dns_pr.c dns_pw.c \
-       dns_sv.c gai_strerror.c gen.c gen_gr.c gen_ho.c \
-       gen_ng.c gen_nw.c gen_pr.c gen_pw.c gen_sv.c \
-       getaddrinfo.c getgrent.c getgrent_r.c gethostent.c \
-       gethostent_r.c getnameinfo.c getnetent.c \
-       getnetent_r.c getnetgrent.c getnetgrent_r.c \
-       getprotoent.c getprotoent_r.c getpwent.c \
-       getpwent_r.c getservent.c getservent_r.c hesiod.c \
-       irp.c irp_gr.c irp_ho.c irp_ng.c irp_nw.c irp_pr.c \
-       irp_pw.c irp_sv.c irpmarshall.c irs_data.c lcl.c \
-       lcl_gr.c lcl_ho.c lcl_ng.c lcl_nw.c lcl_pr.c \
-       lcl_pw.c lcl_sv.c nis.c nis_gr.c nis_ho.c nis_ng.c \
-       nis_nw.c nis_pr.c nis_pw.c nis_sv.c nul_ng.c util.c
-
-.PATH: ${BIND_DIR}/lib/bind/nameser
-SRCS+= ns_date.c ns_name.c ns_netint.c \
-       ns_parse.c ns_print.c  ns_samedomain.c \
-       ns_sign.c ns_ttl.c ns_verify.c
-
-.PATH: ${BIND_DIR}/lib/bind/resolv
-SRCS+= herror.c mtctxres.c res_comp.c res_data.c \
-       res_debug.c res_findzonecut.c res_init.c \
-       res_mkquery.c res_mkupdate.c res_query.c \
-       res_send.c res_sendsigned.c res_update.c
-
-.endif
-
-.PATH: ${BIND_DIR}/lib/bind/dst
-CFLAGS+=-DHMAC_MD5 -DUSE_MD5
-SRCS+= dst_api.c hmac_link.c md5_dgst.c support.c
-
-.PATH: ${BIND_DIR}/lib/bind/isc
-SRCS+= assertions.c base64.c bitncmp.c ctl_clnt.c \
-       ctl_p.c ctl_srvr.c ev_connects.c ev_files.c \
-       ev_streams.c ev_timers.c ev_waits.c \
-       eventlib.c heap.c hex.c logging.c \
-       memcluster.c movefile.c tree.c
-
-.PATH: ${BIND_DIR}/lib/bind/bsd
-SRCS+= gettimeofday.c
-
-WARNS?=        0
-
-INTERNALLIB=           true
-
-.include <bsd.lib.mk>
-
diff --git a/lib/libbind/port_after.h b/lib/libbind/port_after.h
deleted file mode 100644 (file)
index 18c770c..0000000
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * Copyright (C) 2004-2008  Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 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: port_after.h.in,v 1.53.128.7 2008/02/28 05:46:12 marka Exp $ */
-
-#ifndef port_after_h
-#define port_after_h
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#if (!defined(BSD)) || (BSD < 199306)
-#include <sys/bitypes.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-#include <inttypes.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-#include <sys/select.h>
-#endif /* HAVE_SYS_SELECT_H */
-
-#ifdef REENABLE_SEND
-#undef send
-#endif
-
-#undef NEED_PSELECT
-#define HAVE_SA_LEN 1
-#undef HAVE_MINIMUM_IFREQ
-#undef NEED_DAEMON
-#undef NEED_STRSEP
-#undef NEED_STRERROR
-#ifdef NEED_STRERROR
-const char *isc_strerror(int);
-#define strerror isc_strerror
-#endif
-#define HAS_INET6_STRUCTS 1
-#define HAVE_SIN6_SCOPE_ID 1
-#undef NEED_IN6ADDR_ANY
-#undef HAS_IN_ADDR6
-#define HAVE_SOCKADDR_STORAGE 1
-#undef NEED_GETTIMEOFDAY
-#define HAVE_STRNDUP 1
-#undef USE_FIONBIO_IOCTL
-#undef INNETGR_ARGS
-#undef SETNETGRENT_ARGS
-#define USE_IFNAMELINKID 1
-#define PORT_NONBLOCK O_NONBLOCK
-
-#ifndef _POSIX_PATH_MAX
-#define _POSIX_PATH_MAX 255
-#endif
-#ifndef PATH_MAX
-#define PATH_MAX _POSIX_PATH_MAX
-#endif
-
-/*
- * We need to know the IPv6 address family number even on IPv4-only systems.
- * Note that this is NOT a protocol constant, and that if the system has its
- * own AF_INET6, different from ours below, all of BIND's libraries and
- * executables will need to be recompiled after the system <sys/socket.h>
- * has had this type added.  The type number below is correct on most BSD-
- * derived systems for which AF_INET6 is defined.
- */
-#ifndef AF_INET6
-#define AF_INET6        24
-#endif
-
-#ifndef PF_INET6
-#define PF_INET6        AF_INET6
-#endif
-
-#ifdef HAS_IN_ADDR6
-/* Map to pre-RFC structure. */
-#define in6_addr in_addr6
-#endif
-
-#ifndef HAS_INET6_STRUCTS
-/* Replace with structure from later rev of O/S if known. */
-struct in6_addr {
-       u_int8_t        s6_addr[16];
-};
-
-#define IN6ADDR_ANY_INIT \
-       {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}
-
-#define IN6ADDR_LOOPBACK_INIT \
-       {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}
-
-/* Replace with structure from later rev of O/S if known. */
-struct sockaddr_in6 {
-#ifdef  HAVE_SA_LEN
-       u_int8_t        sin6_len;       /* length of this struct */
-       u_int8_t        sin6_family;    /* AF_INET6 */
-#else
-       u_int16_t       sin6_family;    /* AF_INET6 */
-#endif
-       u_int16_t       sin6_port;      /* transport layer port # */
-       u_int32_t       sin6_flowinfo;  /* IPv6 flow information */
-       struct in6_addr sin6_addr;      /* IPv6 address */
-       u_int32_t       sin6_scope_id;  /* set of interfaces for a scope */
-};
-#endif  /* HAS_INET6_STRUCTS */
-
-#ifdef BROKEN_IN6ADDR_INIT_MACROS
-#undef IN6ADDR_ANY_INIT
-#undef IN6ADDR_LOOPBACK_INIT
-#endif
-
-#ifdef _AIX
-#ifndef IN6ADDR_ANY_INIT
-#define IN6ADDR_ANY_INIT {{{ 0, 0, 0, 0 }}}
-#endif
-#ifndef IN6ADDR_LOOPBACK_INIT
-#if BYTE_ORDER == BIG_ENDIAN
-#define IN6ADDR_LOOPBACK_INIT {{{ 0, 0, 0, 1 }}}
-#else
-#define IN6ADDR_LOOPBACK_INIT {{{0, 0, 0, 0x01000000}}}
-#endif
-#endif
-#endif
-
-#ifndef IN6ADDR_ANY_INIT
-#ifdef s6_addr
-#define IN6ADDR_ANY_INIT \
-       {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}}
-#else
-#define IN6ADDR_ANY_INIT \
-       {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }}
-#endif
-
-#endif
-#ifndef IN6ADDR_LOOPBACK_INIT
-#ifdef s6_addr
-#define IN6ADDR_LOOPBACK_INIT \
-       {{{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-           0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}}
-#else
-#define IN6ADDR_LOOPBACK_INIT \
-       {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
-          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 }}
-#endif
-#endif
-
-#ifndef HAVE_SOCKADDR_STORAGE
-#define __SS_MAXSIZE 128
-#define __SS_ALLIGSIZE (sizeof (long))
-
-struct sockaddr_storage {
-#ifdef  HAVE_SA_LEN
-       u_int8_t        ss_len;       /* address length */
-       u_int8_t        ss_family;    /* address family */
-       char            __ss_pad1[__SS_ALLIGSIZE - 2 * sizeof(u_int8_t)];
-       long            __ss_align;
-       char            __ss_pad2[__SS_MAXSIZE - 2 * __SS_ALLIGSIZE];
-#else
-       u_int16_t       ss_family;    /* address family */
-       char            __ss_pad1[__SS_ALLIGSIZE - sizeof(u_int16_t)];
-       long            __ss_align;
-       char            __ss_pad2[__SS_MAXSIZE - 2 * __SS_ALLIGSIZE];
-#endif
-};
-#endif
-
-
-#if !defined(HAS_INET6_STRUCTS) || defined(NEED_IN6ADDR_ANY)
-#define in6addr_any isc_in6addr_any
-extern const struct in6_addr in6addr_any;
-#endif
-
-/*
- * IN6_ARE_ADDR_EQUAL, IN6_IS_ADDR_UNSPECIFIED, IN6_IS_ADDR_V4COMPAT and
- * IN6_IS_ADDR_V4MAPPED are broken in glibc 2.1.
- */
-#ifdef __GLIBC__
-#if __GLIBC__ < 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ < 2)
-#undef IN6_ARE_ADDR_EQUAL
-#undef IN6_IS_ADDR_UNSPECIFIED
-#undef IN6_IS_ADDR_V4COMPAT
-#undef IN6_IS_ADDR_V4MAPPED
-#endif
-#endif
-
-#ifndef IN6_ARE_ADDR_EQUAL
-#define IN6_ARE_ADDR_EQUAL(a,b) \
-   (memcmp(&(a)->s6_addr[0], &(b)->s6_addr[0], sizeof(struct in6_addr)) == 0)
-#endif
-
-#ifndef IN6_IS_ADDR_UNSPECIFIED
-#define IN6_IS_ADDR_UNSPECIFIED(a)      \
-       IN6_ARE_ADDR_EQUAL(a, &in6addr_any)
-#endif
-
-#ifndef IN6_IS_ADDR_LOOPBACK
-extern const struct in6_addr isc_in6addr_loopback;
-#define IN6_IS_ADDR_LOOPBACK(a) \
-       IN6_ARE_ADDR_EQUAL(a, &isc_in6addr_loopback)
-#endif
-
-#ifndef IN6_IS_ADDR_V4MAPPED
-#define IN6_IS_ADDR_V4MAPPED(a)        \
-       ((a)->s6_addr[0] == 0x00 && (a)->s6_addr[1] == 0x00 && \
-       (a)->s6_addr[2] == 0x00 && (a)->s6_addr[3] == 0x00 && \
-       (a)->s6_addr[4] == 0x00 && (a)->s6_addr[5] == 0x00 && \
-       (a)->s6_addr[6] == 0x00 && (a)->s6_addr[9] == 0x00 && \
-       (a)->s6_addr[8] == 0x00 && (a)->s6_addr[9] == 0x00 && \
-       (a)->s6_addr[10] == 0xff && (a)->s6_addr[11] == 0xff)
-#endif
-
-#ifndef IN6_IS_ADDR_SITELOCAL
-#define IN6_IS_ADDR_SITELOCAL(a)        \
-       (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
-#endif
-
-#ifndef IN6_IS_ADDR_LINKLOCAL
-#define IN6_IS_ADDR_LINKLOCAL(a)        \
-       (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
-#endif
-
-#ifndef IN6_IS_ADDR_MULTICAST
-#define IN6_IS_ADDR_MULTICAST(a)        ((a)->s6_addr[0] == 0xff)
-#endif
-
-#ifndef __IPV6_ADDR_MC_SCOPE
-#define __IPV6_ADDR_MC_SCOPE(a)         ((a)->s6_addr[1] & 0x0f)
-#endif
-
-#ifndef __IPV6_ADDR_SCOPE_SITELOCAL
-#define __IPV6_ADDR_SCOPE_SITELOCAL 0x05
-#endif
-#ifndef __IPV6_ADDR_SCOPE_ORGLOCAL
-#define __IPV6_ADDR_SCOPE_ORGLOCAL  0x08
-#endif
-
-#ifndef IN6_IS_ADDR_MC_SITELOCAL
-#define IN6_IS_ADDR_MC_SITELOCAL(a)     \
-       (IN6_IS_ADDR_MULTICAST(a) &&    \
-        (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_SITELOCAL))
-#endif
-
-#ifndef IN6_IS_ADDR_MC_ORGLOCAL
-#define IN6_IS_ADDR_MC_ORGLOCAL(a)      \
-       (IN6_IS_ADDR_MULTICAST(a) &&    \
-        (__IPV6_ADDR_MC_SCOPE(a) == __IPV6_ADDR_SCOPE_ORGLOCAL))
-#endif
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 256
-#endif
-
-#ifndef INET6_ADDRSTRLEN
-/* sizeof("aaaa:bbbb:cccc:dddd:eeee:ffff:123.123.123.123") */
-#define INET6_ADDRSTRLEN 46
-#endif
-
-#ifndef MIN
-#define MIN(x,y) (((x) <= (y)) ? (x) : (y))
-#endif
-
-#ifndef MAX
-#define MAX(x,y) (((x) >= (y)) ? (x) : (y))
-#endif
-
-#ifdef NEED_DAEMON
-int daemon(int nochdir, int noclose);
-#endif
-
-#ifdef NEED_STRSEP
-char * strsep(char **stringp, const char *delim);
-#endif
-
-#ifndef ALIGN
-#define ALIGN(p) (((uintptr_t)(p) + (sizeof(long) - 1)) & ~(sizeof(long) - 1))
-#endif
-
-#ifdef NEED_SETGROUPENT
-int setgroupent(int stayopen);
-#endif
-
-#ifdef NEED_GETGROUPLIST
-int getgrouplist(GETGROUPLIST_ARGS);
-#endif
-
-#ifdef POSIX_GETGRNAM_R
-int
-__posix_getgrnam_r(const char *, struct group *, char *, int, struct group **);
-#endif
-
-#ifdef NEED_GETGRNAM_R
-int
-getgrnam_r(const char *,  struct group *, char *, size_t, struct group **);
-#endif
-
-#ifdef POSIX_GETGRGID_R
-int
-__posix_getgrgid_r(gid_t, struct group *, char *, int, struct group **) ;
-#endif
-
-#ifdef NEED_GETGRGID_R
-int
-getgrgid_r(gid_t, struct group *, char *, size_t, struct group **);
-#endif
-
-#ifdef NEED_GETGRENT_R
-GROUP_R_RETURN getgrent_r(struct group *gptr, GROUP_R_ARGS);
-#endif
-
-#ifdef NEED_SETGRENT_R
-GROUP_R_SET_RETURN setgrent_r(GROUP_R_ENT_ARGS);
-#endif
-
-#ifdef NEED_ENDGRENT_R
-GROUP_R_END_RETURN endgrent_r(GROUP_R_ENT_ARGS);
-#endif
-
-#if defined(NEED_INNETGR_R) && defined(NGR_R_RETURN)
-NGR_R_RETURN
-innetgr_r(const char *, const char *, const char *, const char *);
-#endif
-
-#ifdef NEED_SETNETGRENT_R
-#ifdef NGR_R_SET_ARGS
-NGR_R_SET_RETURN setnetgrent_r(NGR_R_SET_CONST char *netgroup, NGR_R_SET_ARGS);
-#else
-NGR_R_SET_RETURN setnetgrent_r(NGR_R_SET_CONST char *netgroup);
-#endif
-#endif
-
-#ifdef NEED_ENDNETGRENT_R
-#ifdef NGR_R_END_ARGS
-NGR_R_END_RETURN endnetgrent_r(NGR_R_END_ARGS);
-#else
-NGR_R_END_RETURN endnetgrent_r(void);
-#endif
-#endif
-
-#ifdef POSIX_GETPWNAM_R
-int
-__posix_getpwnam_r(const char *login,  struct passwd *pwptr,
-               char *buf, size_t buflen, struct passwd **result);
-#endif
-
-#ifdef NEED_GETPWNAM_R
-int
-getpwnam_r(const char *login,  struct passwd *pwptr,
-               char *buf, size_t buflen, struct passwd **result);
-#endif
-
-#ifdef POSIX_GETPWUID_R
-int
-__posix_getpwuid_r(uid_t uid, struct passwd *pwptr,
-               char *buf, int buflen, struct passwd **result);
-#endif
-
-#ifdef NEED_GETPWUID_R
-int
-getpwuid_r(uid_t uid, struct passwd *pwptr,
-               char *buf, size_t buflen, struct passwd **result);
-#endif
-
-#ifdef NEED_SETPWENT_R
-#ifdef PASS_R_ENT_ARGS
-PASS_R_SET_RETURN setpwent_r(PASS_R_ENT_ARGS);
-#else
-PASS_R_SET_RETURN setpwent_r(void);
-#endif
-
-#endif
-
-#ifdef NEED_SETPASSENT_R
-#ifdef PASS_R_ENT_ARGS
-PASS_R_SET_RETURN setpassent_r(int stayopen, PASS_R_ENT_ARGS);
-#else
-PASS_R_SET_RETURN setpassent_r(int stayopen);
-#endif
-#endif
-
-#ifdef NEED_GETPWENT_R
-PASS_R_RETURN getpwent_r(struct passwd *pwptr, PASS_R_ARGS);
-#endif
-
-#ifdef NEED_ENDPWENT_R
-void endpwent_r(void);
-#endif
-
-#ifdef NEED_SETPASSENT
-int setpassent(int stayopen);
-#endif
-
-#define gettimeofday isc__gettimeofday
-#ifdef NEED_GETTIMEOFDAY
-int isc__gettimeofday(struct timeval *tvp, struct _TIMEZONE *tzp);
-#else
-int isc__gettimeofday(struct timeval *tp, struct timezone *tzp);
-#endif
-
-int getnetgrent(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
-               NGR_R_CONST char **domainp);
-
-#ifdef NGR_R_ARGS
-int getnetgrent_r(NGR_R_CONST char **machinep, NGR_R_CONST char **userp,
-                 NGR_R_CONST char **domainp, NGR_R_ARGS);
-#endif
-
-#ifdef SETNETGRENT_ARGS
-void setnetgrent(SETNETGRENT_ARGS);
-#else
-void setnetgrent(const char *netgroup);
-#endif
-
-void endnetgrent(void);
-
-#ifdef INNETGR_ARGS
-int innetgr(INNETGR_ARGS);
-#else
-int innetgr(const char *netgroup, const char *machine,
-           const char *user, const char *domain);
-#endif
-
-#ifdef NGR_R_SET_ARGS
-NGR_R_SET_RETURN
-setnetgrent_r(NGR_R_SET_CONST char *netgroup, NGR_R_SET_ARGS);
-#else
-NGR_R_SET_RETURN
-setnetgrent_r(NGR_R_SET_CONST char *netgroup);
-#endif
-
-#ifdef NEED_STRTOUL
-unsigned long strtoul(const char *, char **, int);
-#endif
-
-#ifdef NEED_SUN4PROTOS
-#include <stdarg.h>
-#ifndef __SIZE_TYPE__
-#define __SIZE_TYPE__ int
-#endif
-struct sockaddr;
-struct iovec;
-struct timeval;
-struct timezone;
-int fprintf(FILE *, const char *, ...);
-int getsockname(int, struct sockaddr *, int *);
-int getpeername(int, struct sockaddr *, int *);
-int socket(int, int, int);
-int connect(int, const struct sockaddr *, int);
-int writev(int, struct iovec *, int);
-int readv(int, struct iovec *, int);
-int send(int, const char *, int, int);
-void bzero(char *, int);
-int recvfrom(int, char *, int, int, struct sockaddr *, int *);
-int syslog(int, const char *, ... );
-int printf(const char *, ...);
-__SIZE_TYPE__ fread(void *, __SIZE_TYPE__, __SIZE_TYPE__, FILE *);
-__SIZE_TYPE__ fwrite(const void *, __SIZE_TYPE__, __SIZE_TYPE__, FILE *);
-int fclose(FILE *);
-int ungetc(int, FILE *);
-int scanf(const char *, ...);
-int sscanf(const char *, const char *, ... );
-int tolower(int);
-int toupper(int);
-int strcasecmp(const char *, const char *);
-int strncasecmp(const char *, const char *, int);
-int select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
-#ifdef gettimeofday
-#undef gettimeofday
-int gettimeofday(struct timeval *, struct timezone *);
-#define gettimeofday isc__gettimeofday
-#else
-int gettimeofday(struct timeval *, struct timezone *);
-#endif
-long strtol(const char*, char **, int);
-int fseek(FILE *, long, int);
-int setsockopt(int, int, int, const char *, int);
-int bind(int, const struct sockaddr *, int);
-void bcopy(char *, char *, int);
-int fputc(char, FILE *);
-int listen(int, int);
-int accept(int, struct sockaddr *, int *);
-int getsockopt(int, int, int, char *, int *);
-int vfprintf(FILE *, const char *, va_list);
-int fflush(FILE *);
-int fgetc(FILE *);
-int fputs(const char *, FILE *);
-int fchown(int, int, int);
-void setbuf(FILE *, char *);
-int gethostname(char *, int);
-int rename(const char *, const char *);
-time_t time(time_t *);
-int fscanf(FILE *, const char *, ...);
-int sscanf(const char *, const char *, ...);
-int ioctl(int, int, caddr_t);
-void perror(const char *);
-
-#if !defined(__USE_FIXED_PROTOTYPES__) && !defined(__cplusplus) && !defined(__STRICT_ANSI__)
-/*
- * 'gcc -ansi' changes the prototype for vsprintf().
- * Use this prototype when 'gcc -ansi' is not in effect.
- */
-char *vsprintf(char *, const char *, va_list);
-#endif
-#endif
-
-#endif
diff --git a/lib/libbind/port_before.h b/lib/libbind/port_before.h
deleted file mode 100644 (file)
index 6802b4f..0000000
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) 2005-2008  Internet Systems Consortium, Inc. ("ISC")
- * Copyright (C) 2001  Internet Software Consortium.
- *
- * Permission to use, copy, modify, and/or distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
- * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
- * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
- * PERFORMANCE OF THIS SOFTWARE.
- */
-
-/* $Id: port_before.h.in,v 1.27.128.3 2008/02/28 05:46:12 marka Exp $ */
-
-#ifndef port_before_h
-#define port_before_h
-#include <config.h>
-
-#ifdef NEED_SUN4PROTOS
-#define _PARAMS(x) x
-#endif
-
-struct group;           /* silence warning */
-struct passwd;          /* silence warning */
-struct timeval;         /* silence warning */
-struct timezone;        /* silence warning */
-
-#ifdef HAVE_SYS_TIMERS_H
-#include <sys/timers.h>
-#endif
-#include <limits.h>
-
-#ifdef ISC_PLATFORM_NEEDTIMESPEC
-#include <time.h>              /* For time_t */
-struct timespec {
-       time_t  tv_sec;         /* seconds */
-       long    tv_nsec;        /* nanoseconds */
-};
-#endif
-#ifndef HAVE_MEMMOVE
-/*#define memmove(a,b,c) bcopy(b,a,c)*/
-#endif
-
-#undef WANT_IRS_GR
-#undef WANT_IRS_NIS
-#undef WANT_IRS_PW
-
-#undef BSD_COMP
-#undef HAVE_POLL
-#undef HAVE_MD5
-#undef SOLARIS2
-
-#undef DO_PTHREADS
-#define GETGROUPLIST_ARGS const char *name, gid_t basegid, gid_t *groups, int *ngroups
-#define GETNETBYADDR_ADDR_T unsigned long int
-#define SETPWENT_VOID 1
-#define SETGRENT_VOID 1
-
-#define NET_R_ARGS char *buf, size_t buflen, struct netent **answerp, int *h_errnop
-#define NET_R_BAD ERANGE
-#define NET_R_COPY buf, buflen
-#define NET_R_COPY_ARGS char *buf, size_t buflen
-#define NET_R_END_RESULT(x) /*empty*/
-#define NET_R_END_RETURN void
-#undef NET_R_ENT_ARGS /*empty*/
-#define NET_R_OK 0
-#define NET_R_RETURN int
-#undef NET_R_SET_RESULT /*empty*/
-#define NET_R_SETANSWER 1
-#define NET_R_SET_RETURN void
-#undef NETENT_DATA
-
-
-#define GROUP_R_SET_RETURN void
-#undef GROUP_R_SET_RESULT /*empty*/
-#define GROUP_R_END_RETURN void
-#define GROUP_R_END_RESULT(x) /*empty*/
-
-#define GROUP_R_ENT_ARGS void
-
-
-
-#define HOST_R_ARGS char *buf, size_t buflen, struct hostent **answerp, int *h_errnop
-#define HOST_R_BAD ERANGE
-#define HOST_R_COPY buf, buflen
-#define HOST_R_COPY_ARGS char *buf, int buflen
-#define HOST_R_END_RESULT(x) /*empty*/
-#define HOST_R_END_RETURN void
-#undef HOST_R_ENT_ARGS /*empty*/
-#define HOST_R_ERRNO *h_errnop = h_errno
-#define HOST_R_OK 0
-#define HOST_R_RETURN int
-#define HOST_R_SETANSWER 1
-#undef HOST_R_SET_RESULT
-#define HOST_R_SET_RETURN void
-#undef HOSTENT_DATA
-
-#define NGR_R_ARGS char *buf, int buflen
-#define NGR_R_BAD (0)
-#define NGR_R_COPY buf, buflen
-#define NGR_R_COPY_ARGS NGR_R_ARGS
-#define NGR_R_CONST
-#define NGR_R_END_RESULT(x)  /*empty*/
-#define NGR_R_END_RETURN void
-#undef NGR_R_END_ARGS /*empty*/
-#define NGR_R_OK 1
-#define NGR_R_RETURN int
-#define NGR_R_SET_CONST const
-#undef NGR_R_SET_RESULT /*empty*/
-#define NGR_R_SET_RETURN void
-#undef NGR_R_SET_ARGS
-
-
-#if !defined(NGR_R_SET_ARGS) && defined(NGR_R_END_ARGS)
-#define NGR_R_SET_ARGS NGR_R_END_ARGS
-#endif
-
-#define PROTO_R_ARGS char *buf, size_t buflen, struct protoent **answerp
-#define PROTO_R_BAD ERANGE
-#define PROTO_R_COPY buf, buflen
-#define PROTO_R_COPY_ARGS char *buf, size_t buflen
-#define PROTO_R_END_RESULT(x) /*empty*/
-#define PROTO_R_END_RETURN void
-#undef PROTO_R_ENT_ARGS /*empty*/
-#undef PROTO_R_ENT_UNUSED
-#define PROTO_R_OK 0
-#define PROTO_R_SETANSWER 1
-#define PROTO_R_RETURN int
-#undef PROTO_R_SET_RESULT
-#define PROTO_R_SET_RETURN void
-#undef PROTOENT_DATA
-
-
-
-
-
-#define PASS_R_END_RESULT(x) /*empty*/
-#define PASS_R_END_RETURN void
-#undef PASS_R_ENT_ARGS
-
-
-#undef PASS_R_SET_RESULT /*empty*/
-#define PASS_R_SET_RETURN void
-
-#define SERV_R_ARGS char *buf, size_t buflen, struct servent **answerp
-#define SERV_R_BAD ERANGE
-#define SERV_R_COPY buf, buflen
-#define SERV_R_COPY_ARGS char *buf, size_t buflen
-#define SERV_R_END_RESULT(x) /*empty*/
-#define SERV_R_END_RETURN void 
-#undef SERV_R_ENT_ARGS /*empty*/
-#undef SERV_R_ENT_UNUSED /*empty*/
-#define SERV_R_OK (0)
-#define SERV_R_SETANSWER 1
-#define SERV_R_RETURN int
-#undef SERV_R_SET_RESULT
-#define SERV_R_SET_RETURN void
-
-
-
-#define DE_CONST(konst, var) \
-       do { \
-               union { const void *k; void *v; } _u; \
-               _u.k = konst; \
-               var = _u.v; \
-       } while (0)
-
-#define UNUSED(x) (x) = (x)
-
-#undef NEED_SOLARIS_BITTYPES
-#define ISC_SOCKLEN_T socklen_t
-
-#ifdef __GNUC__
-#define ISC_FORMAT_PRINTF(fmt, args) \
-       __attribute__((__format__(__printf__, fmt, args)))
-#else
-#define ISC_FORMAT_PRINTF(fmt, args)
-#endif
-
-/* Pull in host order macros when _XOPEN_SOURCE_EXTENDED is defined. */
-#if defined(__hpux) && defined(_XOPEN_SOURCE_EXTENDED)
-#include <sys/byteorder.h>
-#endif
-
-#endif
-
-/*! \file */
diff --git a/lib/libbind9/Makefile b/lib/libbind9/Makefile
deleted file mode 100644 (file)
index ccec89e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-# $DragonFly: src/lib/libbind9/Makefile,v 1.1 2006/09/20 21:48:39 victor Exp $
-
-BIND_DIR=${.CURDIR}/../../contrib/bind
-.include "${BIND_DIR}/lib/isc/api"
-CFLAGS+= -I${.CURDIR}/../../usr.sbin/named \
-       -I${.CURDIR}/../../usr.sbin/named/include \
-       -I${BIND_DIR}/lib/bind9/include
-
-.if ${MACHINE_ARCH} == "i386"
-CFLAGS+= -I${BIND_DIR}/lib/isc/x86_32/include
-CFLAGS+= -DISC_PLATFORM_USETHREADS
-CFLAGS+= -DISC_PLATFORM_USEGCCASM
-.endif
-.if ${MACHINE_ARCH} == "x86_64"
-CFLAGS+= -I${BIND_DIR}/lib/isc/x86_64/include
-CFLAGS+= -DISC_PLATFORM_USETHREADS
-CFLAGS+= -DISC_PLATFORM_USESTDASM
-.endif
-.include "${.CURDIR}/../../usr.sbin/named/Makefile.inc"
-.include "${BIND_DIR}/lib/bind9/api"
-
-LIB=           bind9
-
-CFLAGS+= -DLIBINTERFACE=${LIBINTERFACE} -DLIBREVISION=${LIBREVISION} -DLIBAGE=${LIBAGE}
-
-.PATH:         ${BIND_DIR}/lib/bind9
-SRCS+=         check.c version.c getaddresses.c
-
-WARNS?=                1
-
-.include <bsd.lib.mk>
-
diff --git a/lib/libc/include/isc/eventlib.h b/lib/libc/include/isc/eventlib.h
new file mode 100644 (file)
index 0000000..1a1ac89
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by 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.
+ */
+
+/* eventlib.h - exported interfaces for eventlib
+ * vix 09sep95 [initial]
+ *
+ * $Id: eventlib.h,v 1.5.574.1 2008/01/23 02:08:11 marka Exp $
+ */
+
+#ifndef _EVENTLIB_H
+#define _EVENTLIB_H
+
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <sys/time.h>
+#include <stdio.h>
+
+#include <isc/platform.h>
+
+#ifndef __P
+# define __EVENTLIB_P_DEFINED
+# ifdef __STDC__
+#  define __P(x) x
+# else
+#  define __P(x) ()
+# endif
+#endif
+
+/* In the absence of branded types... */
+typedef struct { void *opaque; } evConnID;
+typedef struct { void *opaque; } evFileID;
+typedef struct { void *opaque; } evStreamID;
+typedef struct { void *opaque; } evTimerID;
+typedef struct { void *opaque; } evWaitID;
+typedef struct { void *opaque; } evContext;
+typedef struct { void *opaque; } evEvent;
+
+#define        evInitID(id) ((id)->opaque = NULL)
+#define        evTestID(id) ((id).opaque != NULL)
+
+typedef void (*evConnFunc)__P((evContext, void *, int, const void *, int,
+                              const void *, int));
+typedef void (*evFileFunc)__P((evContext, void *, int, int));
+typedef        void (*evStreamFunc)__P((evContext, void *, int, int));
+typedef void (*evTimerFunc)__P((evContext, void *,
+                               struct timespec, struct timespec));
+typedef        void (*evWaitFunc)__P((evContext, void *, const void *));
+
+typedef        struct { unsigned char mask[256/8]; } evByteMask;
+#define        EV_BYTEMASK_BYTE(b) ((b) / 8)
+#define        EV_BYTEMASK_MASK(b) (1 << ((b) % 8))
+#define        EV_BYTEMASK_SET(bm, b) \
+       ((bm).mask[EV_BYTEMASK_BYTE(b)] |= EV_BYTEMASK_MASK(b))
+#define        EV_BYTEMASK_CLR(bm, b) \
+       ((bm).mask[EV_BYTEMASK_BYTE(b)] &= ~EV_BYTEMASK_MASK(b))
+#define        EV_BYTEMASK_TST(bm, b) \
+       ((bm).mask[EV_BYTEMASK_BYTE(b)] & EV_BYTEMASK_MASK(b))
+
+#define        EV_POLL         1
+#define        EV_WAIT         2
+#define        EV_NULL         4
+
+#define        EV_READ         1
+#define        EV_WRITE        2
+#define        EV_EXCEPT       4
+
+#define EV_WASNONBLOCKING 8    /* Internal library use. */
+
+/* eventlib.c */
+#define evCreate       __evCreate
+#define evSetDebug     __evSetDebug
+#define evDestroy      __evDestroy
+#define evGetNext      __evGetNext
+#define evDispatch     __evDispatch
+#define evDrop         __evDrop
+#define evMainLoop     __evMainLoop
+#define evHighestFD    __evHighestFD
+#define evGetOption    __evGetOption
+#define evSetOption    __evSetOption
+
+int  evCreate __P((evContext *));
+void evSetDebug __P((evContext, int, FILE *));
+int  evDestroy __P((evContext));
+int  evGetNext __P((evContext, evEvent *, int));
+int  evDispatch __P((evContext, evEvent));
+void evDrop __P((evContext, evEvent));
+int  evMainLoop __P((evContext));
+int  evHighestFD __P((evContext));
+int  evGetOption __P((evContext *, const char *, int *));
+int  evSetOption __P((evContext *, const char *, int));
+
+/* ev_connects.c */
+#define evListen       __evListen
+#define evConnect      __evConnect
+#define evCancelConn   __evCancelConn
+#define evHold         __evHold
+#define evUnhold       __evUnhold
+#define evTryAccept    __evTryAccept
+
+int evListen __P((evContext, int, int, evConnFunc, void *, evConnID *));
+int evConnect __P((evContext, int, const void *, int,
+                  evConnFunc, void *, evConnID *));
+int evCancelConn __P((evContext, evConnID));
+int evHold __P((evContext, evConnID));
+int evUnhold __P((evContext, evConnID));
+int evTryAccept __P((evContext, evConnID, int *));
+
+/* ev_files.c */
+#define evSelectFD     __evSelectFD
+#define evDeselectFD   __evDeselectFD
+
+int evSelectFD __P((evContext, int, int, evFileFunc, void *, evFileID *));
+int evDeselectFD __P((evContext, evFileID));
+
+/* ev_streams.c */
+#define evConsIovec    __evConsIovec
+#define evWrite                __evWrite
+#define evRead         __evRead
+#define evTimeRW       __evTimeRW
+#define evUntimeRW     __evUntimeRW
+#define        evCancelRW      __evCancelRW
+
+struct iovec evConsIovec __P((void *, size_t));
+int evWrite __P((evContext, int, const struct iovec *, int,
+                evStreamFunc func, void *, evStreamID *));
+int evRead __P((evContext, int, const struct iovec *, int,
+               evStreamFunc func, void *, evStreamID *));
+int evTimeRW __P((evContext, evStreamID, evTimerID timer));
+int evUntimeRW __P((evContext, evStreamID));
+int evCancelRW __P((evContext, evStreamID));
+
+/* ev_timers.c */
+#define evConsTime     __evConsTime
+#define evAddTime      __evAddTime
+#define evSubTime      __evSubTime
+#define evCmpTime      __evCmpTime
+#define        evTimeSpec      __evTimeSpec
+#define        evTimeVal       __evTimeVal
+
+#define evNowTime              __evNowTime
+#define evUTCTime              __evUTCTime
+#define evLastEventTime                __evLastEventTime
+#define evSetTimer             __evSetTimer
+#define evClearTimer           __evClearTimer
+#define evConfigTimer          __evConfigTimer
+#define evResetTimer           __evResetTimer
+#define evSetIdleTimer         __evSetIdleTimer
+#define evClearIdleTimer       __evClearIdleTimer
+#define evResetIdleTimer       __evResetIdleTimer
+#define evTouchIdleTimer       __evTouchIdleTimer
+
+struct timespec evConsTime __P((time_t sec, long nsec));
+struct timespec evAddTime __P((struct timespec, struct timespec));
+struct timespec evSubTime __P((struct timespec, struct timespec));
+struct timespec evNowTime __P((void));
+struct timespec evUTCTime __P((void));
+struct timespec evLastEventTime __P((evContext));
+struct timespec evTimeSpec __P((struct timeval));
+struct timeval evTimeVal __P((struct timespec));
+int evCmpTime __P((struct timespec, struct timespec));
+int evSetTimer __P((evContext, evTimerFunc, void *, struct timespec,
+                   struct timespec, evTimerID *));
+int evClearTimer __P((evContext, evTimerID));
+int evConfigTimer __P((evContext, evTimerID, const char *param,
+                     int value));
+int evResetTimer __P((evContext, evTimerID, evTimerFunc, void *,
+                     struct timespec, struct timespec));
+int evSetIdleTimer __P((evContext, evTimerFunc, void *, struct timespec,
+                       evTimerID *));
+int evClearIdleTimer __P((evContext, evTimerID));
+int evResetIdleTimer __P((evContext, evTimerID, evTimerFunc, void *,
+                         struct timespec));
+int evTouchIdleTimer __P((evContext, evTimerID));
+
+/* ev_waits.c */
+#define evWaitFor      __evWaitFor
+#define evDo           __evDo
+#define evUnwait       __evUnwait
+#define evDefer                __evDefer
+
+int evWaitFor __P((evContext, const void *, evWaitFunc, void *, evWaitID *));
+int evDo __P((evContext, const void *));
+int evUnwait __P((evContext, evWaitID));
+int evDefer __P((evContext, evWaitFunc, void *));
+
+#ifdef __EVENTLIB_P_DEFINED
+# undef __P
+#endif
+
+#endif /*_EVENTLIB_H*/
+
+/*! \file */
diff --git a/lib/libc/include/isc/list.h b/lib/libc/include/isc/list.h
new file mode 100644 (file)
index 0000000..3222240
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1997,1999 by 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 LIST_H
+#define LIST_H 1
+#ifdef _LIBC
+#include <assert.h>
+#define INSIST(cond)   assert(cond)
+#else
+#include <isc/assertions.h>
+#endif
+#define LIST(type) struct { type *head, *tail; }
+#define INIT_LIST(list) \
+       do { (list).head = NULL; (list).tail = NULL; } while (0)
+
+#define LINK(type) struct { type *prev, *next; }
+#define INIT_LINK_TYPE(elt, link, type) \
+       do { \
+               (elt)->link.prev = (type *)(-1); \
+               (elt)->link.next = (type *)(-1); \
+       } while (0)
+#define INIT_LINK(elt, link) \
+       INIT_LINK_TYPE(elt, link, void)
+#define LINKED(elt, link) ((void *)((elt)->link.prev) != (void *)(-1))
+
+#define HEAD(list) ((list).head)
+#define TAIL(list) ((list).tail)
+#define EMPTY(list) ((list).head == NULL)
+
+#define PREPEND(list, elt, link) \
+       do { \
+               INSIST(!LINKED(elt, link));\
+               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 APPEND(list, elt, link) \
+       do { \
+               INSIST(!LINKED(elt, link));\
+               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 UNLINK_TYPE(list, elt, link, type) \
+       do { \
+               INSIST(LINKED(elt, link));\
+               if ((elt)->link.next != NULL) \
+                       (elt)->link.next->link.prev = (elt)->link.prev; \
+               else { \
+                       INSIST((list).tail == (elt)); \
+                       (list).tail = (elt)->link.prev; \
+               } \
+               if ((elt)->link.prev != NULL) \
+                       (elt)->link.prev->link.next = (elt)->link.next; \
+               else { \
+                       INSIST((list).head == (elt)); \
+                       (list).head = (elt)->link.next; \
+               } \
+               INIT_LINK_TYPE(elt, link, type); \
+       } while (0)
+#define UNLINK(list, elt, link) \
+       UNLINK_TYPE(list, elt, link, void)
+
+#define PREV(elt, link) ((elt)->link.prev)
+#define NEXT(elt, link) ((elt)->link.next)
+
+#define INSERT_BEFORE(list, before, elt, link) \
+       do { \
+               INSIST(!LINKED(elt, link));\
+               if ((before)->link.prev == NULL) \
+                       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 INSERT_AFTER(list, after, elt, link) \
+       do { \
+               INSIST(!LINKED(elt, link));\
+               if ((after)->link.next == NULL) \
+                       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 ENQUEUE(list, elt, link) APPEND(list, elt, link)
+#define DEQUEUE(list, elt, link) UNLINK(list, elt, link)
+
+#endif /* LIST_H */
+/*! \file */
diff --git a/lib/libc/include/resolv_mt.h b/lib/libc/include/resolv_mt.h
new file mode 100644 (file)
index 0000000..27963a1
--- /dev/null
@@ -0,0 +1,47 @@
+#ifndef _RESOLV_MT_H
+#define _RESOLV_MT_H
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+/* Access functions for the libresolv private interface */
+
+int    __res_enable_mt(void);
+int    __res_disable_mt(void);
+
+/* Per-thread context */
+
+typedef struct {
+int    no_hosts_fallback_private;
+int    retry_save;
+int    retry_private;
+char   inet_nsap_ntoa_tmpbuf[255*3];
+char   sym_ntos_unname[20];
+char   sym_ntop_unname[20];
+char   p_option_nbuf[40];
+char   p_time_nbuf[40];
+char   precsize_ntoa_retbuf[sizeof "90000000.00"];
+char   loc_ntoa_tmpbuf[sizeof
+"1000 60 60.000 N 1000 60 60.000 W -12345678.00m 90000000.00m 90000000.00m 90000000.00m"];
+char   p_secstodate_output[15];
+} mtctxres_t;
+
+/* Thread-specific data (TSD) */
+
+mtctxres_t     *___mtctxres(void);
+#define mtctxres       (___mtctxres())
+
+/* Various static data that should be TSD */
+
+#define sym_ntos_unname                (mtctxres->sym_ntos_unname)
+#define sym_ntop_unname                (mtctxres->sym_ntop_unname)
+#define inet_nsap_ntoa_tmpbuf  (mtctxres->inet_nsap_ntoa_tmpbuf)
+#define p_option_nbuf          (mtctxres->p_option_nbuf)
+#define p_time_nbuf            (mtctxres->p_time_nbuf)
+#define precsize_ntoa_retbuf   (mtctxres->precsize_ntoa_retbuf)
+#define loc_ntoa_tmpbuf                (mtctxres->loc_ntoa_tmpbuf)
+#define p_secstodate_output    (mtctxres->p_secstodate_output)
+
+#endif /* _RESOLV_MT_H */
diff --git a/lib/libc/inet/inet_addr.c b/lib/libc/inet/inet_addr.c
new file mode 100644 (file)
index 0000000..b532873
--- /dev/null
@@ -0,0 +1,218 @@
+/*
+ * 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.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)inet_addr.c  8.1 (Berkeley) 6/17/93";
+static const char rcsid[] = "$Id: inet_addr.c,v 1.5 2005/04/27 04:56:19 sra Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <ctype.h>
+
+#include "port_after.h"
+
+/*%
+ * Ascii internet address interpretation routine.
+ * The value returned is in network order.
+ */
+in_addr_t
+inet_addr(const char *cp) {
+       struct in_addr val;
+
+       if (inet_aton(cp, &val))
+               return (val.s_addr);
+       return (INADDR_NONE);
+}
+
+/*%
+ * 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
+inet_aton(const char *cp, struct in_addr *addr) {
+       u_long val;
+       int base, n;
+       char c;
+       u_int8_t parts[4];
+       u_int8_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((unsigned char)c))
+                       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 (;;) {
+                       if (isascii(c) && isdigit((unsigned char)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((unsigned char)c)) {
+                               val = (val << 4) |
+                                       (c + 10 - (islower((unsigned char)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 > 0xffU)
+                               return (0);
+                       *pp++ = val;
+                       c = *++cp;
+               } else
+                       break;
+       }
+       /*
+        * Check for trailing characters.
+        */
+       if (c != '\0' && (!isascii(c) || !isspace((unsigned char)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 > 0xffffffU)
+                       return (0);
+               val |= parts[0] << 24;
+               break;
+
+       case 3:                         /*%< a.b.c -- 8.8.16 bits */
+               if (val > 0xffffU)
+                       return (0);
+               val |= (parts[0] << 24) | (parts[1] << 16);
+               break;
+
+       case 4:                         /*%< a.b.c.d -- 8.8.8.8 bits */
+               if (val > 0xffU)
+                       return (0);
+               val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
+               break;
+       }
+       if (addr != NULL)
+               addr->s_addr = htonl(val);
+       return (1);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_addr
+__weak_reference(__inet_addr, inet_addr);
+#undef inet_aton
+__weak_reference(__inet_aton, inet_aton);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_cidr_ntop.c b/lib/libc/inet/inet_cidr_ntop.c
new file mode 100644 (file)
index 0000000..bf960a8
--- /dev/null
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1998,1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: inet_cidr_ntop.c,v 1.7 2006/10/11 02:18:18 marka Exp $";
+#endif
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+static char *
+inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size);
+static char *
+inet_cidr_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size);
+
+/*%
+ * char *
+ * inet_cidr_ntop(af, src, bits, dst, size)
+ *     convert network address from network to presentation format.
+ *     "src"'s size is determined from its "af".
+ * return:
+ *     pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ *     192.5.5.1/28 has a nonzero host part, which means it isn't a network
+ *     as called for by inet_net_ntop() but it can be a host address with
+ *     an included netmask.
+ * author:
+ *     Paul Vixie (ISC), October 1998
+ */
+char *
+inet_cidr_ntop(int af, const void *src, int bits, char *dst, size_t size) {
+       switch (af) {
+       case AF_INET:
+               return (inet_cidr_ntop_ipv4(src, bits, dst, size));
+       case AF_INET6:
+               return (inet_cidr_ntop_ipv6(src, bits, dst, size));
+       default:
+               errno = EAFNOSUPPORT;
+               return (NULL);
+       }
+}
+
+static int
+decoct(const u_char *src, int bytes, char *dst, size_t size) {
+       char *odst = dst;
+       char *t;
+       int b;
+
+       for (b = 1; b <= bytes; b++) {
+               if (size < sizeof "255.")
+                       return (0);
+               t = dst;
+               dst += SPRINTF((dst, "%u", *src++));
+               if (b != bytes) {
+                       *dst++ = '.';
+                       *dst = '\0';
+               }
+               size -= (size_t)(dst - t);
+       }
+       return (dst - odst);
+}
+
+/*%
+ * static char *
+ * inet_cidr_ntop_ipv4(src, bits, dst, size)
+ *     convert IPv4 network address from network to presentation format.
+ *     "src"'s size is determined from its "af".
+ * return:
+ *     pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ *     network byte order assumed.  this means 192.5.5.240/28 has
+ *     0b11110000 in its fourth octet.
+ * author:
+ *     Paul Vixie (ISC), October 1998
+ */
+static char *
+inet_cidr_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) {
+       char *odst = dst;
+       size_t len = 4;
+       size_t b;
+       size_t bytes;
+
+       if ((bits < -1) || (bits > 32)) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
+       /* Find number of significant bytes in address. */
+       if (bits == -1)
+               len = 4;
+       else
+               for (len = 1, b = 1 ; b < 4U; b++)
+                       if (*(src + b))
+                               len = b + 1;
+
+       /* Format whole octets plus nonzero trailing octets. */
+       bytes = (((bits <= 0) ? 1 : bits) + 7) / 8;
+       if (len > bytes)
+               bytes = len;
+       b = decoct(src, bytes, dst, size);
+       if (b == 0U)
+               goto emsgsize;
+       dst += b;
+       size -= b;
+
+       if (bits != -1) {
+               /* Format CIDR /width. */
+               if (size < sizeof "/32")
+                       goto emsgsize;
+               dst += SPRINTF((dst, "/%u", bits));
+       }
+
+       return (odst);
+
+ emsgsize:
+       errno = EMSGSIZE;
+       return (NULL);
+}
+static char *
+inet_cidr_ntop_ipv6(const u_char *src, int bits, 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/128"];
+       char *tp;
+       struct { int base, len; } best, cur;
+       u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
+       int i;
+
+       if ((bits < -1) || (bits > 128)) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
+       /*
+        * 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;
+       best.len = 0;
+       cur.base = -1;
+       cur.len = 0;
+       for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+               if (words[i] == 0) {
+                       if (cur.base == -1)
+                               cur.base = i, cur.len = 1;
+                       else
+                               cur.len++;
+               } else {
+                       if (cur.base != -1) {
+                               if (best.base == -1 || cur.len > best.len)
+                                       best = cur;
+                               cur.base = -1;
+                       }
+               }
+       }
+       if (cur.base != -1) {
+               if (best.base == -1 || cur.len > best.len)
+                       best = cur;
+       }
+       if (best.base != -1 && best.len < 2)
+               best.base = -1;
+
+       /*
+        * Format the result.
+        */
+       tp = tmp;
+       for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+               /* Are we inside the best run of 0x00's? */
+               if (best.base != -1 && i >= best.base &&
+                   i < (best.base + best.len)) {
+                       if (i == best.base)
+                               *tp++ = ':';
+                       continue;
+               }
+               /* Are we following an initial run of 0x00s or any real hex? */
+               if (i != 0)
+                       *tp++ = ':';
+               /* Is this address an encapsulated IPv4? */
+               if (i == 6 && best.base == 0 && (best.len == 6 ||
+                   (best.len == 7 && words[7] != 0x0001) ||
+                   (best.len == 5 && words[5] == 0xffff))) {
+                       int n;
+
+                       if (src[15] || bits == -1 || bits > 120)
+                               n = 4;
+                       else if (src[14] || bits > 112)
+                               n = 3;
+                       else
+                               n = 2;
+                       n = decoct(src+12, n, tp, sizeof tmp - (tp - tmp));
+                       if (n == 0) {
+                               errno = EMSGSIZE;
+                               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';
+
+       if (bits != -1)
+               tp += SPRINTF((tp, "/%u", bits));
+
+       /*
+        * Check for overflow, copy, and we're done.
+        */
+       if ((size_t)(tp - tmp) > size) {
+               errno = EMSGSIZE;
+               return (NULL);
+       }
+       strcpy(dst, tmp);
+       return (dst);
+}
+
+/*! \file */
diff --git a/lib/libc/inet/inet_cidr_pton.c b/lib/libc/inet/inet_cidr_pton.c
new file mode 100644 (file)
index 0000000..1d3ce8e
--- /dev/null
@@ -0,0 +1,282 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1998,1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: inet_cidr_pton.c,v 1.6 2005/04/27 04:56:19 sra Exp $";
+#endif
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#ifdef _LIBC
+#include <assert.h>
+#define                INSIST(x)       assert(x)
+#else
+#include <isc/assertions.h>
+#endif
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+static int     inet_cidr_pton_ipv4 __P((const char *src, u_char *dst,
+                                        int *bits, int ipv6));
+static int     inet_cidr_pton_ipv6 __P((const char *src, u_char *dst,
+                                        int *bits));
+
+static int     getbits(const char *, int ipv6);
+
+/*%
+ * int
+ * inet_cidr_pton(af, src, dst, *bits)
+ *     convert network address from presentation to network format.
+ *     accepts inet_pton()'s input for this "af" plus trailing "/CIDR".
+ *     "dst" is assumed large enough for its "af".  "bits" is set to the
+ *     /CIDR prefix length, which can have defaults (like /32 for IPv4).
+ * return:
+ *     -1 if an error occurred (inspect errno; ENOENT means bad format).
+ *     0 if successful conversion occurred.
+ * note:
+ *     192.5.5.1/28 has a nonzero host part, which means it isn't a network
+ *     as called for by inet_net_pton() but it can be a host address with
+ *     an included netmask.
+ * author:
+ *     Paul Vixie (ISC), October 1998
+ */
+int
+inet_cidr_pton(int af, const char *src, void *dst, int *bits) {
+       switch (af) {
+       case AF_INET:
+               return (inet_cidr_pton_ipv4(src, dst, bits, 0));
+       case AF_INET6:
+               return (inet_cidr_pton_ipv6(src, dst, bits));
+       default:
+               errno = EAFNOSUPPORT;
+               return (-1);
+       }
+}
+
+static const char digits[] = "0123456789";
+
+static int
+inet_cidr_pton_ipv4(const char *src, u_char *dst, int *pbits, int ipv6) {
+       const u_char *odst = dst;
+       int n, ch, tmp, bits;
+       size_t size = 4;
+
+       /* Get the mantissa. */
+       while (ch = *src++, (isascii(ch) && isdigit(ch))) {
+               tmp = 0;
+               do {
+                       n = strchr(digits, ch) - digits;
+                       INSIST(n >= 0 && n <= 9);
+                       tmp *= 10;
+                       tmp += n;
+                       if (tmp > 255)
+                               goto enoent;
+               } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
+               if (size-- == 0U)
+                       goto emsgsize;
+               *dst++ = (u_char) tmp;
+               if (ch == '\0' || ch == '/')
+                       break;
+               if (ch != '.')
+                       goto enoent;
+       }
+
+       /* Get the prefix length if any. */
+       bits = -1;
+       if (ch == '/' && dst > odst) {
+               bits = getbits(src, ipv6);
+               if (bits == -2)
+                       goto enoent;
+       } else if (ch != '\0')
+               goto enoent;
+
+       /* Prefix length can default to /32 only if all four octets spec'd. */
+       if (bits == -1) {
+               if (dst - odst == 4)
+                       bits = ipv6 ? 128 : 32;
+               else
+                       goto enoent;
+       }
+
+       /* If nothing was written to the destination, we found no address. */
+       if (dst == odst)
+               goto enoent;
+
+       /* If prefix length overspecifies mantissa, life is bad. */
+       if (((bits - (ipv6 ? 96 : 0)) / 8) > (dst - odst))
+               goto enoent;
+
+       /* Extend address to four octets. */
+       while (size-- > 0U)
+               *dst++ = 0;
+
+       *pbits = bits;
+       return (0);
+
+ enoent:
+       errno = ENOENT;
+       return (-1);
+
+ emsgsize:
+       errno = EMSGSIZE;
+       return (-1);
+}
+
+static int
+inet_cidr_pton_ipv6(const char *src, u_char *dst, int *pbits) {
+       static const char xdigits_l[] = "0123456789abcdef",
+                         xdigits_u[] = "0123456789ABCDEF";
+       u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+       const char *xdigits, *curtok;
+       int ch, saw_xdigit;
+       u_int val;
+       int bits;
+
+       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;
+       saw_xdigit = 0;
+       val = 0;
+       bits = -1;
+       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 (val > 0xffff)
+                               return (0);
+                       saw_xdigit = 1;
+                       continue;
+               }
+               if (ch == ':') {
+                       curtok = src;
+                       if (!saw_xdigit) {
+                               if (colonp)
+                                       return (0);
+                               colonp = tp;
+                               continue;
+                       } else if (*src == '\0') {
+                               return (0);
+                       }
+                       if (tp + NS_INT16SZ > endp)
+                               return (0);
+                       *tp++ = (u_char) (val >> 8) & 0xff;
+                       *tp++ = (u_char) val & 0xff;
+                       saw_xdigit = 0;
+                       val = 0;
+                       continue;
+               }
+               if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+                   inet_cidr_pton_ipv4(curtok, tp, &bits, 1) == 0) {
+                       tp += NS_INADDRSZ;
+                       saw_xdigit = 0;
+                       break;  /*%< '\\0' was seen by inet_pton4(). */
+               }
+               if (ch == '/') {
+                       bits = getbits(src, 1);
+                       if (bits == -2)
+                               goto enoent;
+                       break;
+               }
+               goto enoent;
+       }
+       if (saw_xdigit) {
+               if (tp + NS_INT16SZ > endp)
+                       goto emsgsize;
+               *tp++ = (u_char) (val >> 8) & 0xff;
+               *tp++ = (u_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)
+                       goto enoent;
+               for (i = 1; i <= n; i++) {
+                       endp[- i] = colonp[n - i];
+                       colonp[n - i] = 0;
+               }
+               tp = endp;
+       }
+
+       memcpy(dst, tmp, NS_IN6ADDRSZ);
+
+       *pbits = bits;
+       return (0);
+
+ enoent:
+       errno = ENOENT;
+       return (-1);
+
+ emsgsize:
+       errno = EMSGSIZE;
+       return (-1);
+}
+
+static int
+getbits(const char *src, int ipv6) {
+       int bits = 0;
+       char *cp, ch;
+       
+       if (*src == '\0')                       /*%< syntax */
+               return (-2);
+       do {
+               ch = *src++;
+               cp = strchr(digits, ch);
+               if (cp == NULL)                 /*%< syntax */
+                       return (-2);
+               bits *= 10;
+               bits += cp - digits;
+               if (bits == 0 && *src != '\0')  /*%< no leading zeros */
+                       return (-2);
+               if (bits > (ipv6 ? 128 : 32))   /*%< range error */
+                       return (-2);
+       } while (*src != '\0');
+
+       return (bits);
+}
+
+/*! \file */
diff --git a/lib/libc/inet/inet_data.c b/lib/libc/inet/inet_data.c
new file mode 100644 (file)
index 0000000..4373a17
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char rcsid[] = "$Id: inet_data.c,v 1.4 2005/04/27 04:56:19 sra Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "port_after.h"
+
+const struct in6_addr isc_in6addr_any = IN6ADDR_ANY_INIT;
+const struct in6_addr isc_in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
+
+/*! \file */
diff --git a/lib/libc/inet/inet_lnaof.c b/lib/libc/inet/inet_lnaof.c
new file mode 100644 (file)
index 0000000..e4be6f7
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1983, 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "port_after.h"
+
+/*%
+ * Return the local network address portion of an
+ * internet address; handles class a/b/c network
+ * number formats.
+ */
+in_addr_t
+inet_lnaof(in)
+       struct in_addr in;
+{
+       in_addr_t i = ntohl(in.s_addr);
+
+       if (IN_CLASSA(i))
+               return ((i)&IN_CLASSA_HOST);
+       else if (IN_CLASSB(i))
+               return ((i)&IN_CLASSB_HOST);
+       else
+               return ((i)&IN_CLASSC_HOST);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_lnaof
+__weak_reference(__inet_lnaof, inet_lnaof);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_makeaddr.c b/lib/libc/inet/inet_makeaddr.c
new file mode 100644 (file)
index 0000000..f41b98d
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 1983, 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)inet_makeaddr.c      8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "port_after.h"
+
+/*%
+ * Formulate an Internet address from network + host.  Used in
+ * building addresses stored in the ifnet structure.
+ */
+struct in_addr
+inet_makeaddr(net, host)
+       in_addr_t net, host;
+{
+       struct in_addr a;
+
+       if (net < 128U)
+               a.s_addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
+       else if (net < 65536U)
+               a.s_addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
+       else if (net < 16777216L)
+               a.s_addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
+       else
+               a.s_addr = net | host;
+       a.s_addr = htonl(a.s_addr);
+       return (a);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_makeaddr
+__weak_reference(__inet_makeaddr, inet_makeaddr);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_net_ntop.c b/lib/libc/inet/inet_net_ntop.c
new file mode 100644 (file)
index 0000000..5d4cea6
--- /dev/null
@@ -0,0 +1,287 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: inet_net_ntop.c,v 1.5 2006/06/20 02:50:14 marka Exp $";
+#endif
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+static char *  inet_net_ntop_ipv4 __P((const u_char *src, int bits,
+                                       char *dst, size_t size));
+static char *  inet_net_ntop_ipv6 __P((const u_char *src, int bits,
+                                       char *dst, size_t size));
+
+/*%
+ * char *
+ * inet_net_ntop(af, src, bits, dst, size)
+ *     convert network number from network to presentation format.
+ *     generates CIDR style result always.
+ * return:
+ *     pointer to dst, or NULL if an error occurred (check errno).
+ * author:
+ *     Paul Vixie (ISC), July 1996
+ */
+char *
+inet_net_ntop(af, src, bits, dst, size)
+       int af;
+       const void *src;
+       int bits;
+       char *dst;
+       size_t size;
+{
+       switch (af) {
+       case AF_INET:
+               return (inet_net_ntop_ipv4(src, bits, dst, size));
+       case AF_INET6:
+               return (inet_net_ntop_ipv6(src, bits, dst, size));
+       default:
+               errno = EAFNOSUPPORT;
+               return (NULL);
+       }
+}
+
+/*%
+ * static char *
+ * inet_net_ntop_ipv4(src, bits, dst, size)
+ *     convert IPv4 network number from network to presentation format.
+ *     generates CIDR style result always.
+ * return:
+ *     pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ *     network byte order assumed.  this means 192.5.5.240/28 has
+ *     0b11110000 in its fourth octet.
+ * author:
+ *     Paul Vixie (ISC), July 1996
+ */
+static char *
+inet_net_ntop_ipv4(src, bits, dst, size)
+       const u_char *src;
+       int bits;
+       char *dst;
+       size_t size;
+{
+       char *odst = dst;
+       char *t;
+       u_int m;
+       int b;
+
+       if (bits < 0 || bits > 32) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
+       if (bits == 0) {
+               if (size < sizeof "0")
+                       goto emsgsize;
+               *dst++ = '0';
+               size--;
+               *dst = '\0';
+       }
+
+       /* Format whole octets. */
+       for (b = bits / 8; b > 0; b--) {
+               if (size <= sizeof "255.")
+                       goto emsgsize;
+               t = dst;
+               dst += SPRINTF((dst, "%u", *src++));
+               if (b > 1) {
+                       *dst++ = '.';
+                       *dst = '\0';
+               }
+               size -= (size_t)(dst - t);
+       }
+
+       /* Format partial octet. */
+       b = bits % 8;
+       if (b > 0) {
+               if (size <= sizeof ".255")
+                       goto emsgsize;
+               t = dst;
+               if (dst != odst)
+                       *dst++ = '.';
+               m = ((1 << b) - 1) << (8 - b);
+               dst += SPRINTF((dst, "%u", *src & m));
+               size -= (size_t)(dst - t);
+       }
+
+       /* Format CIDR /width. */
+       if (size <= sizeof "/32")
+               goto emsgsize;
+       dst += SPRINTF((dst, "/%u", bits));
+       return (odst);
+
+ emsgsize:
+       errno = EMSGSIZE;
+       return (NULL);
+}
+
+/*%
+ * static char *
+ * inet_net_ntop_ipv6(src, bits, fakebits, dst, size)
+ *     convert IPv6 network number from network to presentation format.
+ *     generates CIDR style result always. Picks the shortest representation
+ *     unless the IP is really IPv4.
+ *     always prints specified number of bits (bits).
+ * return:
+ *     pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ *     network byte order assumed.  this means 192.5.5.240/28 has
+ *     0x11110000 in its fourth octet.
+ * author:
+ *     Vadim Kogan (UCB), June 2001
+ *  Original version (IPv4) by Paul Vixie (ISC), July 1996
+ */
+
+static char *
+inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) {
+       u_int   m;
+       int     b;
+       int     p;
+       int     zero_s, zero_l, tmp_zero_s, tmp_zero_l;
+       int     i;
+       int     is_ipv4 = 0;
+       unsigned char inbuf[16];
+       char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")];
+       char    *cp;
+       int     words;
+       u_char  *s;
+
+       if (bits < 0 || bits > 128) {
+               errno = EINVAL;
+               return (NULL);
+       }
+
+       cp = outbuf;
+
+       if (bits == 0) {
+               *cp++ = ':';
+               *cp++ = ':';
+               *cp = '\0';
+       } else {
+               /* Copy src to private buffer.  Zero host part. */      
+               p = (bits + 7) / 8;
+               memcpy(inbuf, src, p);
+               memset(inbuf + p, 0, 16 - p);
+               b = bits % 8;
+               if (b != 0) {
+                       m = ~0 << (8 - b);
+                       inbuf[p-1] &= m;
+               }
+
+               s = inbuf;
+
+               /* how many words need to be displayed in output */
+               words = (bits + 15) / 16;
+               if (words == 1)
+                       words = 2;
+               
+               /* Find the longest substring of zero's */
+               zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0;
+               for (i = 0; i < (words * 2); i += 2) {
+                       if ((s[i] | s[i+1]) == 0) {
+                               if (tmp_zero_l == 0)
+                                       tmp_zero_s = i / 2;
+                               tmp_zero_l++;
+                       } else {
+                               if (tmp_zero_l && zero_l < tmp_zero_l) {
+                                       zero_s = tmp_zero_s;
+                                       zero_l = tmp_zero_l;
+                                       tmp_zero_l = 0;
+                               }
+                       }
+               }
+
+               if (tmp_zero_l && zero_l < tmp_zero_l) {
+                       zero_s = tmp_zero_s;
+                       zero_l = tmp_zero_l;
+               }
+
+               if (zero_l != words && zero_s == 0 && ((zero_l == 6) ||
+                   ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) ||
+                   ((zero_l == 7 && s[14] != 0 && s[15] != 1)))))
+                       is_ipv4 = 1;
+
+               /* Format whole words. */
+               for (p = 0; p < words; p++) {
+                       if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) {
+                               /* Time to skip some zeros */
+                               if (p == zero_s)
+                                       *cp++ = ':';
+                               if (p == words - 1)
+                                       *cp++ = ':';
+                               s++;
+                               s++;
+                               continue;
+                       }
+
+                       if (is_ipv4 && p > 5 ) {
+                               *cp++ = (p == 6) ? ':' : '.';
+                               cp += SPRINTF((cp, "%u", *s++));
+                               /* we can potentially drop the last octet */
+                               if (p != 7 || bits > 120) {
+                                       *cp++ = '.';
+                                       cp += SPRINTF((cp, "%u", *s++));
+                               }
+                       } else {
+                               if (cp != outbuf)
+                                       *cp++ = ':';
+                               cp += SPRINTF((cp, "%x", *s * 256 + s[1]));
+                               s += 2;
+                       }
+               }
+       }
+       /* Format CIDR /width. */
+       sprintf(cp, "/%u", bits);
+       if (strlen(outbuf) + 1 > size)
+               goto emsgsize;
+       strcpy(dst, outbuf);
+       
+       return (dst);
+
+emsgsize:
+       errno = EMSGSIZE;
+       return (NULL);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_net_ntop
+__weak_reference(__inet_net_ntop, inet_net_ntop);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_net_pton.c b/lib/libc/inet/inet_net_pton.c
new file mode 100644 (file)
index 0000000..a55cc11
--- /dev/null
@@ -0,0 +1,420 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: inet_net_pton.c,v 1.8.672.1 2008/08/26 04:42:38 marka Exp $";
+#endif
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#ifdef _LIBC
+#include <assert.h>
+#define INSIST(cond)   assert(cond)
+#else
+#include <isc/assertions.h>
+#endif
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/*%
+ * static int
+ * inet_net_pton_ipv4(src, dst, size)
+ *     convert IPv4 network number from presentation to network format.
+ *     accepts hex octets, hex strings, decimal octets, and /CIDR.
+ *     "size" is in bytes and describes "dst".
+ * return:
+ *     number of bits, either imputed classfully or specified with /CIDR,
+ *     or -1 if some failure occurred (check errno).  ENOENT means it was
+ *     not an IPv4 network specification.
+ * note:
+ *     network byte order assumed.  this means 192.5.5.240/28 has
+ *     0b11110000 in its fourth octet.
+ * author:
+ *     Paul Vixie (ISC), June 1996
+ */
+static int
+inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) {
+       static const char xdigits[] = "0123456789abcdef";
+       static const char digits[] = "0123456789";
+       int n, ch, tmp = 0, dirty, bits;
+       const u_char *odst = dst;
+
+       ch = *src++;
+       if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
+           && isascii((unsigned char)(src[1]))
+           && isxdigit((unsigned char)(src[1]))) {
+               /* Hexadecimal: Eat nybble string. */
+               if (size <= 0U)
+                       goto emsgsize;
+               dirty = 0;
+               src++;  /*%< skip x or X. */
+               while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) {
+                       if (isupper(ch))
+                               ch = tolower(ch);
+                       n = strchr(xdigits, ch) - xdigits;
+                       INSIST(n >= 0 && n <= 15);
+                       if (dirty == 0)
+                               tmp = n;
+                       else
+                               tmp = (tmp << 4) | n;
+                       if (++dirty == 2) {
+                               if (size-- <= 0U)
+                                       goto emsgsize;
+                               *dst++ = (u_char) tmp;
+                               dirty = 0;
+                       }
+               }
+               if (dirty) {  /*%< Odd trailing nybble? */
+                       if (size-- <= 0U)
+                               goto emsgsize;
+                       *dst++ = (u_char) (tmp << 4);
+               }
+       } else if (isascii(ch) && isdigit(ch)) {
+               /* Decimal: eat dotted digit string. */
+               for (;;) {
+                       tmp = 0;
+                       do {
+                               n = strchr(digits, ch) - digits;
+                               INSIST(n >= 0 && n <= 9);
+                               tmp *= 10;
+                               tmp += n;
+                               if (tmp > 255)
+                                       goto enoent;
+                       } while ((ch = *src++) != '\0' &&
+                                isascii(ch) && isdigit(ch));
+                       if (size-- <= 0U)
+                               goto emsgsize;
+                       *dst++ = (u_char) tmp;
+                       if (ch == '\0' || ch == '/')
+                               break;
+                       if (ch != '.')
+                               goto enoent;
+                       ch = *src++;
+                       if (!isascii(ch) || !isdigit(ch))
+                               goto enoent;
+               }
+       } else
+               goto enoent;
+
+       bits = -1;
+       if (ch == '/' && isascii((unsigned char)(src[0])) &&
+           isdigit((unsigned char)(src[0])) && dst > odst) {
+               /* CIDR width specifier.  Nothing can follow it. */
+               ch = *src++;    /*%< Skip over the /. */
+               bits = 0;
+               do {
+                       n = strchr(digits, ch) - digits;
+                       INSIST(n >= 0 && n <= 9);
+                       bits *= 10;
+                       bits += n;
+                       if (bits > 32)
+                               goto enoent;
+               } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
+               if (ch != '\0')
+                       goto enoent;
+       }
+
+       /* Firey death and destruction unless we prefetched EOS. */
+       if (ch != '\0')
+               goto enoent;
+
+       /* If nothing was written to the destination, we found no address. */
+       if (dst == odst)
+               goto enoent;
+       /* If no CIDR spec was given, infer width from net class. */
+       if (bits == -1) {
+               if (*odst >= 240)       /*%< Class E */
+                       bits = 32;
+               else if (*odst >= 224)  /*%< Class D */
+                       bits = 8;
+               else if (*odst >= 192)  /*%< Class C */
+                       bits = 24;
+               else if (*odst >= 128)  /*%< Class B */
+                       bits = 16;
+               else                    /*%< Class A */
+                       bits = 8;
+               /* If imputed mask is narrower than specified octets, widen. */
+               if (bits < ((dst - odst) * 8))
+                       bits = (dst - odst) * 8;
+               /*
+                * If there are no additional bits specified for a class D
+                * address adjust bits to 4.
+                */
+               if (bits == 8 && *odst == 224)
+                       bits = 4;
+       }
+       /* Extend network to cover the actual mask. */
+       while (bits > ((dst - odst) * 8)) {
+               if (size-- <= 0U)
+                       goto emsgsize;
+               *dst++ = '\0';
+       }
+       return (bits);
+
+ enoent:
+       errno = ENOENT;
+       return (-1);
+
+ emsgsize:
+       errno = EMSGSIZE;
+       return (-1);
+}
+
+static int
+getbits(const char *src, int *bitsp) {
+       static const char digits[] = "0123456789";
+       int n;
+       int val;
+       char ch;
+
+       val = 0;
+       n = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               pch = strchr(digits, ch);
+               if (pch != NULL) {
+                       if (n++ != 0 && val == 0)       /*%< no leading zeros */
+                               return (0);
+                       val *= 10;
+                       val += (pch - digits);
+                       if (val > 128)                  /*%< range */
+                               return (0);
+                       continue;
+               }
+               return (0);
+       }
+       if (n == 0)
+               return (0);
+       *bitsp = val;
+       return (1);
+}
+
+static int
+getv4(const char *src, u_char *dst, int *bitsp) {
+       static const char digits[] = "0123456789";
+       u_char *odst = dst;
+       int n;
+       u_int val;
+       char ch;
+
+       val = 0;
+       n = 0;
+       while ((ch = *src++) != '\0') {
+               const char *pch;
+
+               pch = strchr(digits, ch);
+               if (pch != NULL) {
+                       if (n++ != 0 && val == 0)       /*%< no leading zeros */
+                               return (0);
+                       val *= 10;
+                       val += (pch - digits);
+                       if (val > 255)                  /*%< range */
+                               return (0);
+                       continue;
+               }
+               if (ch == '.' || ch == '/') {
+                       if (dst - odst > 3)             /*%< too many octets? */
+                               return (0);
+                       *dst++ = val;
+                       if (ch == '/')
+                               return (getbits(src, bitsp));
+                       val = 0;
+                       n = 0;
+                       continue;
+               }
+               return (0);
+       }
+       if (n == 0)
+               return (0);
+       if (dst - odst > 3)             /*%< too many octets? */
+               return (0);
+       *dst++ = val;
+       return (1);
+}
+
+static int
+inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) {
+       static const char xdigits_l[] = "0123456789abcdef",
+                         xdigits_u[] = "0123456789ABCDEF";
+       u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+       const char *xdigits, *curtok;
+       int ch, saw_xdigit;
+       u_int val;
+       int digits;
+       int bits;
+       size_t bytes;
+       int words;
+       int ipv4;
+
+       memset((tp = tmp), '\0', NS_IN6ADDRSZ);
+       endp = tp + NS_IN6ADDRSZ;
+       colonp = NULL;
+       /* Leading :: requires some special handling. */
+       if (*src == ':')
+               if (*++src != ':')
+                       goto enoent;
+       curtok = src;
+       saw_xdigit = 0;
+       val = 0;
+       digits = 0;
+       bits = -1;
+       ipv4 = 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 (++digits > 4)
+                               goto enoent;
+                       saw_xdigit = 1;
+                       continue;
+               }
+               if (ch == ':') {
+                       curtok = src;
+                       if (!saw_xdigit) {
+                               if (colonp)
+                                       goto enoent;
+                               colonp = tp;
+                               continue;
+                       } else if (*src == '\0')
+                               goto enoent;
+                       if (tp + NS_INT16SZ > endp)
+                               return (0);
+                       *tp++ = (u_char) (val >> 8) & 0xff;
+                       *tp++ = (u_char) val & 0xff;
+                       saw_xdigit = 0;
+                       digits = 0;
+                       val = 0;
+                       continue;
+               }
+               if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
+                    getv4(curtok, tp, &bits) > 0) {
+                       tp += NS_INADDRSZ;
+                       saw_xdigit = 0;
+                       ipv4 = 1;
+                       break;  /*%< '\\0' was seen by inet_pton4(). */
+               }
+               if (ch == '/' && getbits(src, &bits) > 0)
+                       break;
+               goto enoent;
+       }
+       if (saw_xdigit) {
+               if (tp + NS_INT16SZ > endp)
+                       goto enoent;
+               *tp++ = (u_char) (val >> 8) & 0xff;
+               *tp++ = (u_char) val & 0xff;
+       }
+       if (bits == -1)
+               bits = 128;
+
+       words = (bits + 15) / 16;
+       if (words < 2)
+               words = 2;
+       if (ipv4)
+               words = 8;
+       endp =  tmp + 2 * words;
+
+       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)
+                       goto enoent;
+               for (i = 1; i <= n; i++) {
+                       endp[- i] = colonp[n - i];
+                       colonp[n - i] = 0;
+               }
+               tp = endp;
+       }
+       if (tp != endp)
+               goto enoent;
+
+       bytes = (bits + 7) / 8;
+       if (bytes > size)
+               goto emsgsize;
+       memcpy(dst, tmp, bytes);
+       return (bits);
+
+ enoent:
+       errno = ENOENT;
+       return (-1);
+
+ emsgsize:
+       errno = EMSGSIZE;
+       return (-1);
+}
+
+/*%
+ * int
+ * inet_net_pton(af, src, dst, size)
+ *     convert network number from presentation to network format.
+ *     accepts hex octets, hex strings, decimal octets, and /CIDR.
+ *     "size" is in bytes and describes "dst".
+ * return:
+ *     number of bits, either imputed classfully or specified with /CIDR,
+ *     or -1 if some failure occurred (check errno).  ENOENT means it was
+ *     not a valid network specification.
+ * author:
+ *     Paul Vixie (ISC), June 1996
+ */
+int
+inet_net_pton(int af, const char *src, void *dst, size_t size) {
+       switch (af) {
+       case AF_INET:
+               return (inet_net_pton_ipv4(src, dst, size));
+       case AF_INET6:
+               return (inet_net_pton_ipv6(src, dst, size));
+       default:
+               errno = EAFNOSUPPORT;
+               return (-1);
+       }
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_net_pton
+__weak_reference(__inet_net_pton, inet_net_pton);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_neta.c b/lib/libc/inet/inet_neta.c
new file mode 100644 (file)
index 0000000..95d6c88
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: inet_neta.c,v 1.3 2005/04/27 04:56:20 sra Exp $";
+#endif
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/*%
+ * char *
+ * inet_neta(src, dst, size)
+ *     format a u_long network number into presentation format.
+ * return:
+ *     pointer to dst, or NULL if an error occurred (check errno).
+ * note:
+ *     format of ``src'' is as for inet_network().
+ * author:
+ *     Paul Vixie (ISC), July 1996
+ */
+char *
+inet_neta(src, dst, size)
+       in_addr_t src;
+       char *dst;
+       size_t size;
+{
+       char *odst = dst;
+       char *tp;
+
+       while (src & 0xffffffff) {
+               u_char b = (src & 0xff000000) >> 24;
+
+               src <<= 8;
+               if (b) {
+                       if (size < sizeof "255.")
+                               goto emsgsize;
+                       tp = dst;
+                       dst += SPRINTF((dst, "%u", b));
+                       if (src != 0L) {
+                               *dst++ = '.';
+                               *dst = '\0';
+                       }
+                       size -= (size_t)(dst - tp);
+               }
+       }
+       if (dst == odst) {
+               if (size < sizeof "0.0.0.0")
+                       goto emsgsize;
+               strcpy(dst, "0.0.0.0");
+       }
+       return (odst);
+
+ emsgsize:
+       errno = EMSGSIZE;
+       return (NULL);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_neta
+__weak_reference(__inet_neta, inet_neta);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_netof.c b/lib/libc/inet/inet_netof.c
new file mode 100644 (file)
index 0000000..c4f11fa
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 1983, 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include "port_after.h"
+
+/*%
+ * Return the network number from an internet
+ * address; handles class a/b/c network #'s.
+ */
+in_addr_t
+inet_netof(in)
+       struct in_addr in;
+{
+       in_addr_t i = ntohl(in.s_addr);
+       
+       if (IN_CLASSA(i))
+               return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
+       else if (IN_CLASSB(i))
+               return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
+       else
+               return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_netof
+__weak_reference(__inet_netof, inet_netof);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_network.c b/lib/libc/inet/inet_network.c
new file mode 100644 (file)
index 0000000..84e7519
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 1983, 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)inet_network.c       8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+
+#include "port_after.h"
+
+/*%
+ * Internet network address interpretation routine.
+ * The library routines call this routine to interpret
+ * network numbers.
+ */
+in_addr_t
+inet_network(cp)
+       const char *cp;
+{
+       in_addr_t val, base, n;
+       char c;
+       in_addr_t parts[4], *pp = parts;
+       int i, digit;
+again:
+       val = 0; base = 10; digit = 0;
+       if (*cp == '0')
+               digit = 1, base = 8, cp++;
+       if (*cp == 'x' || *cp == 'X')
+               base = 16, cp++;
+       while ((c = *cp) != 0) {
+               if (isdigit((unsigned char)c)) {
+                       if (base == 8U && (c == '8' || c == '9'))
+                               return (INADDR_NONE);
+                       val = (val * base) + (c - '0');
+                       cp++;
+                       digit = 1;
+                       continue;
+               }
+               if (base == 16U && isxdigit((unsigned char)c)) {
+                       val = (val << 4) +
+                             (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
+                       cp++;
+                       digit = 1;
+                       continue;
+               }
+               break;
+       }
+       if (!digit)
+               return (INADDR_NONE);
+       if (pp >= parts + 4 || val > 0xffU)
+               return (INADDR_NONE);
+       if (*cp == '.') {
+               *pp++ = val, cp++;
+               goto again;
+       }
+       if (*cp && !isspace(*cp&0xff))
+               return (INADDR_NONE);
+       *pp++ = val;
+       n = pp - parts;
+       if (n > 4U)
+               return (INADDR_NONE);
+       for (val = 0, i = 0; i < n; i++) {
+               val <<= 8;
+               val |= parts[i] & 0xff;
+       }
+       return (val);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_network
+__weak_reference(__inet_network, inet_network);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_ntoa.c b/lib/libc/inet/inet_ntoa.c
new file mode 100644 (file)
index 0000000..67b04cb
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1983, 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)inet_ntoa.c  8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$Id: inet_ntoa.c,v 1.2 2005/04/27 04:56:21 sra Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "port_after.h"
+
+/*%
+ * Convert network-format internet address
+ * to base 256 d.d.d.d representation.
+ */
+/*const*/ char *
+inet_ntoa(struct in_addr in) {
+       static char ret[18];
+
+       strcpy(ret, "[inet_ntoa error]");
+       (void) inet_ntop(AF_INET, &in, ret, sizeof ret);
+       return (ret);
+}
+
+#ifdef _LIBC
+char *
+inet_ntoa_r(struct in_addr in, char *buf, socklen_t size)
+{
+
+       inet_ntop(AF_INET, &in, buf, size);
+       return (buf);
+}
+
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+*/
+#undef inet_ntoa
+__weak_reference(__inet_ntoa, inet_ntoa);
+__weak_reference(__inet_ntoa_r, inet_ntoa_r);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_ntop.c b/lib/libc/inet/inet_ntop.c
new file mode 100644 (file)
index 0000000..ef9c3c3
--- /dev/null
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: inet_ntop.c,v 1.5 2005/11/03 22:59:52 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include "arpa/inet.h"
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/*%
+ * 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 __P((const u_char *src, char *dst, size_t size));
+static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
+
+/* char *
+ * inet_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 *
+inet_ntop(af, src, dst, size)
+       int af;
+       const void *src;
+       char *dst;
+       socklen_t size;
+{
+       switch (af) {
+       case AF_INET:
+               return (inet_ntop4(src, dst, size));
+       case AF_INET6:
+               return (inet_ntop6(src, dst, size));
+       default:
+               errno = EAFNOSUPPORT;
+               return (NULL);
+       }
+       /* NOTREACHED */
+}
+
+/* const char *
+ * inet_ntop4(src, dst, size)
+ *     format an IPv4 address
+ * return:
+ *     `dst' (as a const)
+ * notes:
+ *     (1) uses no statics
+ *     (2) takes a u_char* not an in_addr as input
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop4(src, dst, size)
+       const u_char *src;
+       char *dst;
+       size_t size;
+{
+       static const char fmt[] = "%u.%u.%u.%u";
+       char tmp[sizeof "255.255.255.255"];
+
+       if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) >= size) {
+               errno = ENOSPC;
+               return (NULL);
+       }
+       strcpy(dst, tmp);
+       return (dst);
+}
+
+/* const char *
+ * inet_ntop6(src, dst, size)
+ *     convert IPv6 binary address into presentation (printable) format
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static const char *
+inet_ntop6(src, dst, size)
+       const u_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;
+       u_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;
+       best.len = 0;
+       cur.base = -1;
+       cur.len = 0;
+       for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+               if (words[i] == 0) {
+                       if (cur.base == -1)
+                               cur.base = i, cur.len = 1;
+                       else
+                               cur.len++;
+               } else {
+                       if (cur.base != -1) {
+                               if (best.base == -1 || cur.len > best.len)
+                                       best = cur;
+                               cur.base = -1;
+                       }
+               }
+       }
+       if (cur.base != -1) {
+               if (best.base == -1 || cur.len > best.len)
+                       best = cur;
+       }
+       if (best.base != -1 && best.len < 2)
+               best.base = -1;
+
+       /*
+        * Format the result.
+        */
+       tp = tmp;
+       for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
+               /* Are we inside the best run of 0x00's? */
+               if (best.base != -1 && i >= best.base &&
+                   i < (best.base + best.len)) {
+                       if (i == best.base)
+                               *tp++ = ':';
+                       continue;
+               }
+               /* Are we following an initial run of 0x00s or any real hex? */
+               if (i != 0)
+                       *tp++ = ':';
+               /* Is this address an encapsulated IPv4? */
+               if (i == 6 && best.base == 0 && (best.len == 6 ||
+                   (best.len == 7 && words[7] != 0x0001) ||
+                   (best.len == 5 && words[5] == 0xffff))) {
+                       if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
+                               return (NULL);
+                       tp += strlen(tp);
+                       break;
+               }
+               tp += 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);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_ntop
+__weak_reference(__inet_ntop, inet_ntop);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/inet_pton.c b/lib/libc/inet/inet_pton.c
new file mode 100644 (file)
index 0000000..6444bb5
--- /dev/null
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: inet_pton.c,v 1.5 2005/07/28 06:51:47 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+#include <string.h>
+#include <errno.h>
+#include "port_after.h"
+
+/*%
+ * 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 __P((const char *src, u_char *dst));
+static int     inet_pton6 __P((const char *src, u_char *dst));
+
+/* int
+ * inet_pton(af, src, 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
+inet_pton(af, src, dst)
+       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 */
+}
+
+/* int
+ * inet_pton4(src, dst)
+ *     like inet_aton() but without all the hexadecimal and shorthand.
+ * return:
+ *     1 if `src' is a valid dotted quad, else 0.
+ * notice:
+ *     does not touch `dst' unless it's returning 1.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton4(src, dst)
+       const char *src;
+       u_char *dst;
+{
+       static const char digits[] = "0123456789";
+       int saw_digit, octets, ch;
+       u_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) {
+                       u_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);
+}
+
+/* int
+ * inet_pton6(src, dst)
+ *     convert presentation level address to network order binary form.
+ * return:
+ *     1 if `src' is a valid [RFC1884 2.2] address, else 0.
+ * notice:
+ *     (1) does not touch `dst' unless it's returning 1.
+ *     (2) :: in a full address is silently ignored.
+ * credit:
+ *     inspired by Mark Andrews.
+ * author:
+ *     Paul Vixie, 1996.
+ */
+static int
+inet_pton6(src, dst)
+       const char *src;
+       u_char *dst;
+{
+       static const char xdigits_l[] = "0123456789abcdef",
+                         xdigits_u[] = "0123456789ABCDEF";
+       u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
+       const char *xdigits, *curtok;
+       int ch, seen_xdigits;
+       u_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;
+                       } else if (*src == '\0') {
+                               return (0);
+                       }
+                       if (tp + NS_INT16SZ > endp)
+                               return (0);
+                       *tp++ = (u_char) (val >> 8) & 0xff;
+                       *tp++ = (u_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++ = (u_char) (val >> 8) & 0xff;
+               *tp++ = (u_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);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_pton
+__weak_reference(__inet_pton, inet_pton);
+#endif
+/*! \file */
diff --git a/lib/libc/inet/nsap_addr.c b/lib/libc/inet/nsap_addr.c
new file mode 100644 (file)
index 0000000..05cfabf
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: nsap_addr.c,v 1.5 2005/07/28 06:51:48 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <resolv.h>
+#include "resolv_mt.h"
+
+#include "port_after.h"
+
+static char
+xtob(int c) {
+       return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
+}
+
+u_int
+inet_nsap_addr(const char *ascii, u_char *binary, int maxlen) {
+       u_char c, nib;
+       u_int len = 0;
+
+       if (ascii[0] != '0' || (ascii[1] != 'x' && ascii[1] != 'X'))
+               return (0);
+       ascii += 2;
+
+       while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
+               if (c == '.' || c == '+' || c == '/')
+                       continue;
+               if (!isascii(c))
+                       return (0);
+               if (islower(c))
+                       c = toupper(c);
+               if (isxdigit(c)) {
+                       nib = xtob(c);
+                       c = *ascii++;
+                       if (c != '\0') {
+                               c = toupper(c);
+                               if (isxdigit(c)) {
+                                       *binary++ = (nib << 4) | xtob(c);
+                                       len++;
+                               } else
+                                       return (0);
+                       }
+                       else
+                               return (0);
+               }
+               else
+                       return (0);
+       }
+       return (len);
+}
+
+char *
+inet_nsap_ntoa(int binlen, const u_char *binary, char *ascii) {
+       int nib;
+       int i;
+       char *tmpbuf = inet_nsap_ntoa_tmpbuf;
+       char *start;
+
+       if (ascii)
+               start = ascii;
+       else {
+               ascii = tmpbuf;
+               start = tmpbuf;
+       }
+
+       *ascii++ = '0';
+       *ascii++ = 'x';
+
+       if (binlen > 255)
+               binlen = 255;
+
+       for (i = 0; i < binlen; i++) {
+               nib = *binary >> 4;
+               *ascii++ = nib + (nib < 10 ? '0' : '7');
+               nib = *binary++ & 0x0f;
+               *ascii++ = nib + (nib < 10 ? '0' : '7');
+               if (((i % 2) == 0 && (i + 1) < binlen))
+                       *ascii++ = '.';
+       }
+       *ascii = '\0';
+       return (start);
+}
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <arpa/inet.h>.
+ */
+#undef inet_nsap_addr
+__weak_reference(__inet_nsap_addr, inet_nsap_addr);
+#undef inet_nsap_ntoa
+__weak_reference(__inet_nsap_ntoa, inet_nsap_ntoa);
+#endif
+/*! \file */
diff --git a/lib/libc/isc/ev_streams.c b/lib/libc/isc/ev_streams.c
new file mode 100644 (file)
index 0000000..eefebf4
--- /dev/null
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by 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.
+ */
+
+/* ev_streams.c - implement asynch stream file IO for the eventlib
+ * vix 04mar96 [initial]
+ */
+
+#if !defined(LINT) && !defined(CODECENTER)
+static const char rcsid[] = "$Id: ev_streams.c,v 1.5 2005/04/27 04:56:36 sra Exp $";
+#endif
+
+#include "port_before.h"
+#ifndef _LIBC
+#include "fd_setsize.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/uio.h>
+
+#include <errno.h>
+
+#include "isc/eventlib.h"
+#ifndef _LIBC
+#include <isc/assertions.h>
+#endif
+#include "eventlib_p.h"
+
+#include "port_after.h"
+
+#ifndef _LIBC
+static int     copyvec(evStream *str, const struct iovec *iov, int iocnt);
+static void    consume(evStream *str, size_t bytes);
+static void    done(evContext opaqueCtx, evStream *str);
+static void    writable(evContext opaqueCtx, void *uap, int fd, int evmask);
+static void    readable(evContext opaqueCtx, void *uap, int fd, int evmask);
+#endif
+
+struct iovec
+evConsIovec(void *buf, size_t cnt) {
+       struct iovec ret;
+
+       memset(&ret, 0xf5, sizeof ret);
+       ret.iov_base = buf;
+       ret.iov_len = cnt;
+       return (ret);
+}
+
+#ifndef _LIBC
+int
+evWrite(evContext opaqueCtx, int fd, const struct iovec *iov, int iocnt,
+       evStreamFunc func, void *uap, evStreamID *id)
+{
+       evContext_p *ctx = opaqueCtx.opaque;
+       evStream *new;
+       int save;
+
+       OKNEW(new);
+       new->func = func;
+       new->uap = uap;
+       new->fd = fd;
+       new->flags = 0;
+       if (evSelectFD(opaqueCtx, fd, EV_WRITE, writable, new, &new->file) < 0)
+               goto free;
+       if (copyvec(new, iov, iocnt) < 0)
+               goto free;
+       new->prevDone = NULL;
+       new->nextDone = NULL;
+       if (ctx->streams != NULL)
+               ctx->streams->prev = new;
+       new->prev = NULL;
+       new->next = ctx->streams;
+       ctx->streams = new;
+       if (id != NULL)
+               id->opaque = new;
+       return (0);
+ free:
+       save = errno;
+       FREE(new);
+       errno = save;
+       return (-1);
+}
+
+int
+evRead(evContext opaqueCtx, int fd, const struct iovec *iov, int iocnt,
+       evStreamFunc func, void *uap, evStreamID *id)
+{
+       evContext_p *ctx = opaqueCtx.opaque;
+       evStream *new;
+       int save;
+
+       OKNEW(new);
+       new->func = func;
+       new->uap = uap;
+       new->fd = fd;
+       new->flags = 0;
+       if (evSelectFD(opaqueCtx, fd, EV_READ, readable, new, &new->file) < 0)
+               goto free;
+       if (copyvec(new, iov, iocnt) < 0)
+               goto free;
+       new->prevDone = NULL;
+       new->nextDone = NULL;
+       if (ctx->streams != NULL)
+               ctx->streams->prev = new;
+       new->prev = NULL;
+       new->next = ctx->streams;
+       ctx->streams = new;
+       if (id)
+               id->opaque = new;
+       return (0);
+ free:
+       save = errno;
+       FREE(new);
+       errno = save;
+       return (-1);
+}
+
+int
+evTimeRW(evContext opaqueCtx, evStreamID id, evTimerID timer) /*ARGSUSED*/ {
+       evStream *str = id.opaque;
+
+       UNUSED(opaqueCtx);
+
+       str->timer = timer;
+       str->flags |= EV_STR_TIMEROK;
+       return (0);
+}
+
+int
+evUntimeRW(evContext opaqueCtx, evStreamID id) /*ARGSUSED*/ {
+       evStream *str = id.opaque;
+
+       UNUSED(opaqueCtx);
+
+       str->flags &= ~EV_STR_TIMEROK;
+       return (0);
+}
+
+int
+evCancelRW(evContext opaqueCtx, evStreamID id) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       evStream *old = id.opaque;
+
+       /*
+        * The streams list is doubly threaded.  First, there's ctx->streams
+        * that's used by evDestroy() to find and cancel all streams.  Second,
+        * there's ctx->strDone (head) and ctx->strLast (tail) which thread
+        * through the potentially smaller number of "IO completed" streams,
+        * used in evGetNext() to avoid scanning the entire list.
+        */
+
+       /* Unlink from ctx->streams. */
+       if (old->prev != NULL)
+               old->prev->next = old->next;
+       else
+               ctx->streams = old->next;
+       if (old->next != NULL)
+               old->next->prev = old->prev;
+
+       /*
+        * If 'old' is on the ctx->strDone list, remove it.  Update
+        * ctx->strLast if necessary.
+        */
+       if (old->prevDone == NULL && old->nextDone == NULL) {
+               /*
+                * Either 'old' is the only item on the done list, or it's
+                * not on the done list.  If the former, then we unlink it
+                * from the list.  If the latter, we leave the list alone.
+                */
+               if (ctx->strDone == old) {
+                       ctx->strDone = NULL;
+                       ctx->strLast = NULL;
+               }
+       } else {
+               if (old->prevDone != NULL)
+                       old->prevDone->nextDone = old->nextDone;
+               else
+                       ctx->strDone = old->nextDone;
+               if (old->nextDone != NULL)
+                       old->nextDone->prevDone = old->prevDone;
+               else
+                       ctx->strLast = old->prevDone;
+       }
+
+       /* Deallocate the stream. */
+       if (old->file.opaque)
+               evDeselectFD(opaqueCtx, old->file);
+       memput(old->iovOrig, sizeof (struct iovec) * old->iovOrigCount);
+       FREE(old);
+       return (0);
+}
+
+/* Copy a scatter/gather vector and initialize a stream handler's IO. */
+static int
+copyvec(evStream *str, const struct iovec *iov, int iocnt) {
+       int i;
+
+       str->iovOrig = (struct iovec *)memget(sizeof(struct iovec) * iocnt);
+       if (str->iovOrig == NULL) {
+               errno = ENOMEM;
+               return (-1);
+       }
+       str->ioTotal = 0;
+       for (i = 0; i < iocnt; i++) {
+               str->iovOrig[i] = iov[i];
+               str->ioTotal += iov[i].iov_len;
+       }
+       str->iovOrigCount = iocnt;
+       str->iovCur = str->iovOrig;
+       str->iovCurCount = str->iovOrigCount;
+       str->ioDone = 0;
+       return (0);
+}
+
+/* Pull off or truncate lead iovec(s). */
+static void
+consume(evStream *str, size_t bytes) {
+       while (bytes > 0U) {
+               if (bytes < (size_t)str->iovCur->iov_len) {
+                       str->iovCur->iov_len -= bytes;
+                       str->iovCur->iov_base = (void *)
+                               ((u_char *)str->iovCur->iov_base + bytes);
+                       str->ioDone += bytes;
+                       bytes = 0;
+               } else {
+                       bytes -= str->iovCur->iov_len;
+                       str->ioDone += str->iovCur->iov_len;
+                       str->iovCur++;
+                       str->iovCurCount--;
+               }
+       }
+}
+
+/* Add a stream to Done list and deselect the FD. */
+static void
+done(evContext opaqueCtx, evStream *str) {
+       evContext_p *ctx = opaqueCtx.opaque;
+
+       if (ctx->strLast != NULL) {
+               str->prevDone = ctx->strLast;
+               ctx->strLast->nextDone = str;
+               ctx->strLast = str;
+       } else {
+               INSIST(ctx->strDone == NULL);
+               ctx->strDone = ctx->strLast = str;
+       }
+       evDeselectFD(opaqueCtx, str->file);
+       str->file.opaque = NULL;
+       /* evDrop() will call evCancelRW() on us. */
+}
+
+/* Dribble out some bytes on the stream.  (Called by evDispatch().) */
+static void
+writable(evContext opaqueCtx, void *uap, int fd, int evmask) {
+       evStream *str = uap;
+       int bytes;
+
+       UNUSED(evmask);
+
+       bytes = writev(fd, str->iovCur, str->iovCurCount);
+       if (bytes > 0) {
+               if ((str->flags & EV_STR_TIMEROK) != 0)
+                       evTouchIdleTimer(opaqueCtx, str->timer);
+               consume(str, bytes);
+       } else {
+               if (bytes < 0 && errno != EINTR) {
+                       str->ioDone = -1;
+                       str->ioErrno = errno;
+               }
+       }
+       if (str->ioDone == -1 || str->ioDone == str->ioTotal)
+               done(opaqueCtx, str);
+}
+
+/* Scoop up some bytes from the stream.  (Called by evDispatch().) */
+static void
+readable(evContext opaqueCtx, void *uap, int fd, int evmask) {
+       evStream *str = uap;
+       int bytes;
+
+       UNUSED(evmask);
+
+       bytes = readv(fd, str->iovCur, str->iovCurCount);
+       if (bytes > 0) {
+               if ((str->flags & EV_STR_TIMEROK) != 0)
+                       evTouchIdleTimer(opaqueCtx, str->timer);
+               consume(str, bytes);
+       } else {
+               if (bytes == 0)
+                       str->ioDone = 0;
+               else {
+                       if (errno != EINTR) {
+                               str->ioDone = -1;
+                               str->ioErrno = errno;
+                       }
+               }
+       }
+       if (str->ioDone <= 0 || str->ioDone == str->ioTotal)
+               done(opaqueCtx, str);
+}
+#endif /* !_LIBC */
+
+/*! \file */
diff --git a/lib/libc/isc/ev_timers.c b/lib/libc/isc/ev_timers.c
new file mode 100644 (file)
index 0000000..735e0e3
--- /dev/null
@@ -0,0 +1,510 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by 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.
+ */
+
+/* ev_timers.c - implement timers for the eventlib
+ * vix 09sep95 [initial]
+ */
+
+#if !defined(LINT) && !defined(CODECENTER)
+static const char rcsid[] = "$Id: ev_timers.c,v 1.6 2005/04/27 04:56:36 sra Exp $";
+#endif
+
+/* Import. */
+
+#include "port_before.h"
+#ifndef _LIBC
+#include "fd_setsize.h"
+#endif
+
+#include <errno.h>
+
+#ifndef _LIBC
+#include <isc/assertions.h>
+#endif
+#include "isc/eventlib.h"
+#include "eventlib_p.h"
+
+#include "port_after.h"
+
+/* Constants. */
+
+#define        MILLION 1000000
+#define BILLION 1000000000
+
+/* Forward. */
+#ifdef _LIBC
+static int     __evOptMonoTime;
+#else
+static int due_sooner(void *, void *);
+static void set_index(void *, int);
+static void free_timer(void *, void *);
+static void print_timer(void *, void *);
+static void idle_timeout(evContext, void *, struct timespec, struct timespec);
+
+/* Private type. */
+
+typedef struct {
+       evTimerFunc     func;
+       void *          uap;
+       struct timespec lastTouched;
+       struct timespec max_idle;
+       evTimer *       timer;
+} idle_timer;
+#endif
+/* Public. */
+
+struct timespec
+evConsTime(time_t sec, long nsec) {
+       struct timespec x;
+
+       x.tv_sec = sec;
+       x.tv_nsec = nsec;
+       return (x);
+}
+
+struct timespec
+evAddTime(struct timespec addend1, struct timespec addend2) {
+       struct timespec x;
+
+       x.tv_sec = addend1.tv_sec + addend2.tv_sec;
+       x.tv_nsec = addend1.tv_nsec + addend2.tv_nsec;
+       if (x.tv_nsec >= BILLION) {
+               x.tv_sec++;
+               x.tv_nsec -= BILLION;
+       }
+       return (x);
+}
+
+struct timespec
+evSubTime(struct timespec minuend, struct timespec subtrahend) {
+       struct timespec x;
+
+       x.tv_sec = minuend.tv_sec - subtrahend.tv_sec;
+       if (minuend.tv_nsec >= subtrahend.tv_nsec)
+               x.tv_nsec = minuend.tv_nsec - subtrahend.tv_nsec;
+       else {
+               x.tv_nsec = BILLION - subtrahend.tv_nsec + minuend.tv_nsec;
+               x.tv_sec--;
+       }
+       return (x);
+}
+
+int
+evCmpTime(struct timespec a, struct timespec b) {
+       long x = a.tv_sec - b.tv_sec;
+
+       if (x == 0L)
+               x = a.tv_nsec - b.tv_nsec;
+       return (x < 0L ? (-1) : x > 0L ? (1) : (0));
+}
+
+struct timespec
+evNowTime() {
+       struct timeval now;
+#ifdef CLOCK_REALTIME
+       struct timespec tsnow;
+       int m = CLOCK_REALTIME;
+
+#ifdef CLOCK_MONOTONIC
+       if (__evOptMonoTime)
+               m = CLOCK_MONOTONIC;
+#endif
+       if (clock_gettime(m, &tsnow) == 0)
+               return (tsnow);
+#endif
+       if (gettimeofday(&now, NULL) < 0)
+               return (evConsTime(0, 0));
+       return (evTimeSpec(now));
+}
+
+struct timespec
+evUTCTime() {
+       struct timeval now;
+#ifdef CLOCK_REALTIME
+       struct timespec tsnow;
+       if (clock_gettime(CLOCK_REALTIME, &tsnow) == 0)
+               return (tsnow);
+#endif
+       if (gettimeofday(&now, NULL) < 0)
+               return (evConsTime(0, 0));
+       return (evTimeSpec(now));
+}
+
+#ifndef _LIBC 
+struct timespec
+evLastEventTime(evContext opaqueCtx) {
+       evContext_p *ctx = opaqueCtx.opaque;
+
+       return (ctx->lastEventTime);
+}
+#endif
+
+struct timespec
+evTimeSpec(struct timeval tv) {
+       struct timespec ts;
+
+       ts.tv_sec = tv.tv_sec;
+       ts.tv_nsec = tv.tv_usec * 1000;
+       return (ts);
+}
+#if !defined(USE_KQUEUE) || !defined(_LIBC)
+struct timeval
+evTimeVal(struct timespec ts) {
+       struct timeval tv;
+
+       tv.tv_sec = ts.tv_sec;
+       tv.tv_usec = ts.tv_nsec / 1000;
+       return (tv);
+}
+#endif
+
+#ifndef _LIBC
+int
+evSetTimer(evContext opaqueCtx,
+          evTimerFunc func,
+          void *uap,
+          struct timespec due,
+          struct timespec inter,
+          evTimerID *opaqueID
+) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       evTimer *id;
+
+       evPrintf(ctx, 1,
+"evSetTimer(ctx %p, func %p, uap %p, due %ld.%09ld, inter %ld.%09ld)\n",
+                ctx, func, uap,
+                (long)due.tv_sec, due.tv_nsec,
+                (long)inter.tv_sec, inter.tv_nsec);
+
+#ifdef __hpux
+       /*
+        * tv_sec and tv_nsec are unsigned.
+        */
+       if (due.tv_nsec >= BILLION)
+               EV_ERR(EINVAL);
+
+       if (inter.tv_nsec >= BILLION)
+               EV_ERR(EINVAL);
+#else
+       if (due.tv_sec < 0 || due.tv_nsec < 0 || due.tv_nsec >= BILLION)
+               EV_ERR(EINVAL);
+
+       if (inter.tv_sec < 0 || inter.tv_nsec < 0 || inter.tv_nsec >= BILLION)
+               EV_ERR(EINVAL);
+#endif
+
+       /* due={0,0} is a magic cookie meaning "now." */
+       if (due.tv_sec == (time_t)0 && due.tv_nsec == 0L)
+               due = evNowTime();
+
+       /* Allocate and fill. */
+       OKNEW(id);
+       id->func = func;
+       id->uap = uap;
+       id->due = due;
+       id->inter = inter;
+
+       if (heap_insert(ctx->timers, id) < 0)
+               return (-1);
+
+       /* Remember the ID if the caller provided us a place for it. */
+       if (opaqueID)
+               opaqueID->opaque = id;
+
+       if (ctx->debug > 7) {
+               evPrintf(ctx, 7, "timers after evSetTimer:\n");
+               (void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
+       }
+
+       return (0);
+}
+
+int
+evClearTimer(evContext opaqueCtx, evTimerID id) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       evTimer *del = id.opaque;
+
+       if (ctx->cur != NULL &&
+           ctx->cur->type == Timer &&
+           ctx->cur->u.timer.this == del) {
+               evPrintf(ctx, 8, "deferring delete of timer (executing)\n");
+               /*
+                * Setting the interval to zero ensures that evDrop() will
+                * clean up the timer.
+                */
+               del->inter = evConsTime(0, 0);
+               return (0);
+       }
+
+       if (heap_element(ctx->timers, del->index) != del)
+               EV_ERR(ENOENT);
+
+       if (heap_delete(ctx->timers, del->index) < 0)
+               return (-1);
+       FREE(del);
+
+       if (ctx->debug > 7) {
+               evPrintf(ctx, 7, "timers after evClearTimer:\n");
+               (void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
+       }
+
+       return (0);
+}
+
+int
+evConfigTimer(evContext opaqueCtx,
+            evTimerID id,
+            const char *param,
+            int value
+) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       evTimer *timer = id.opaque;
+       int result=0;
+
+       UNUSED(value);
+
+       if (heap_element(ctx->timers, timer->index) != timer)
+               EV_ERR(ENOENT);
+
+       if (strcmp(param, "rate") == 0)
+               timer->mode |= EV_TMR_RATE;
+       else if (strcmp(param, "interval") == 0)
+               timer->mode &= ~EV_TMR_RATE;
+       else
+               EV_ERR(EINVAL);
+
+       return (result);
+}
+
+int
+evResetTimer(evContext opaqueCtx,
+            evTimerID id,
+            evTimerFunc func,
+            void *uap,
+            struct timespec due,
+            struct timespec inter
+) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       evTimer *timer = id.opaque;
+       struct timespec old_due;
+       int result=0;
+
+       if (heap_element(ctx->timers, timer->index) != timer)
+               EV_ERR(ENOENT);
+
+#ifdef __hpux
+       /*
+        * tv_sec and tv_nsec are unsigned.
+        */
+       if (due.tv_nsec >= BILLION)
+               EV_ERR(EINVAL);
+
+       if (inter.tv_nsec >= BILLION)
+               EV_ERR(EINVAL);
+#else
+       if (due.tv_sec < 0 || due.tv_nsec < 0 || due.tv_nsec >= BILLION)
+               EV_ERR(EINVAL);
+
+       if (inter.tv_sec < 0 || inter.tv_nsec < 0 || inter.tv_nsec >= BILLION)
+               EV_ERR(EINVAL);
+#endif
+
+       old_due = timer->due;
+
+       timer->func = func;
+       timer->uap = uap;
+       timer->due = due;
+       timer->inter = inter;
+
+       switch (evCmpTime(due, old_due)) {
+       case -1:
+               result = heap_increased(ctx->timers, timer->index);
+               break;
+       case 0:
+               result = 0;
+               break;
+       case 1:
+               result = heap_decreased(ctx->timers, timer->index);
+               break;
+       }
+
+       if (ctx->debug > 7) {
+               evPrintf(ctx, 7, "timers after evResetTimer:\n");
+               (void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
+       }
+
+       return (result);
+}
+
+int
+evSetIdleTimer(evContext opaqueCtx,
+               evTimerFunc func,
+               void *uap,
+               struct timespec max_idle,
+               evTimerID *opaqueID
+) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       idle_timer *tt;
+
+       /* Allocate and fill. */
+       OKNEW(tt);
+       tt->func = func;
+       tt->uap = uap;
+       tt->lastTouched = ctx->lastEventTime;
+       tt->max_idle = max_idle;
+
+       if (evSetTimer(opaqueCtx, idle_timeout, tt,
+                      evAddTime(ctx->lastEventTime, max_idle),
+                      max_idle, opaqueID) < 0) {
+               FREE(tt);
+               return (-1);
+       }
+
+       tt->timer = opaqueID->opaque;
+
+       return (0);
+}
+
+int
+evClearIdleTimer(evContext opaqueCtx, evTimerID id) {
+       evTimer *del = id.opaque;
+       idle_timer *tt = del->uap;
+
+       FREE(tt);
+       return (evClearTimer(opaqueCtx, id));
+}
+
+int
+evResetIdleTimer(evContext opaqueCtx,
+                evTimerID opaqueID,
+                evTimerFunc func,
+                void *uap,
+                struct timespec max_idle
+) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       evTimer *timer = opaqueID.opaque;
+       idle_timer *tt = timer->uap;
+
+       tt->func = func;
+       tt->uap = uap;
+       tt->lastTouched = ctx->lastEventTime;
+       tt->max_idle = max_idle;
+
+       return (evResetTimer(opaqueCtx, opaqueID, idle_timeout, tt,
+                            evAddTime(ctx->lastEventTime, max_idle),
+                            max_idle));
+}
+
+int
+evTouchIdleTimer(evContext opaqueCtx, evTimerID id) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       evTimer *t = id.opaque;
+       idle_timer *tt = t->uap;
+
+       tt->lastTouched = ctx->lastEventTime;
+
+       return (0);
+}
+
+/* Public to the rest of eventlib. */
+
+heap_context
+evCreateTimers(const evContext_p *ctx) {
+
+       UNUSED(ctx);
+
+       return (heap_new(due_sooner, set_index, 2048));
+}
+
+void
+evDestroyTimers(const evContext_p *ctx) {
+       (void) heap_for_each(ctx->timers, free_timer, NULL);
+       (void) heap_free(ctx->timers);
+}
+
+/* Private. */
+
+static int
+due_sooner(void *a, void *b) {
+       evTimer *a_timer, *b_timer;
+
+       a_timer = a;
+       b_timer = b;
+       return (evCmpTime(a_timer->due, b_timer->due) < 0);
+}
+
+static void
+set_index(void *what, int index) {
+       evTimer *timer;
+
+       timer = what;
+       timer->index = index;
+}
+
+static void
+free_timer(void *what, void *uap) {
+       evTimer *t = what;
+
+       UNUSED(uap);
+
+       FREE(t);
+}
+
+static void
+print_timer(void *what, void *uap) {
+       evTimer *cur = what;
+       evContext_p *ctx = uap;
+
+       cur = what;
+       evPrintf(ctx, 7,
+           "  func %p, uap %p, due %ld.%09ld, inter %ld.%09ld\n",
+                cur->func, cur->uap,
+                (long)cur->due.tv_sec, cur->due.tv_nsec,
+                (long)cur->inter.tv_sec, cur->inter.tv_nsec);
+}
+
+static void
+idle_timeout(evContext opaqueCtx,
+            void *uap,
+            struct timespec due,
+            struct timespec inter
+) {
+       evContext_p *ctx = opaqueCtx.opaque;
+       idle_timer *this = uap;
+       struct timespec idle;
+
+       UNUSED(due);
+       UNUSED(inter);
+       
+       idle = evSubTime(ctx->lastEventTime, this->lastTouched);
+       if (evCmpTime(idle, this->max_idle) >= 0) {
+               (this->func)(opaqueCtx, this->uap, this->timer->due,
+                            this->max_idle);
+               /*
+                * Setting the interval to zero will cause the timer to
+                * be cleaned up in evDrop().
+                */
+               this->timer->inter = evConsTime(0, 0);
+               FREE(this);
+       } else {
+               /* evDrop() will reschedule the timer. */
+               this->timer->inter = evSubTime(this->max_idle, idle);
+       }
+}
+#endif /* !_LIBC */
+
+/*! \file */
diff --git a/lib/libc/isc/eventlib_p.h b/lib/libc/isc/eventlib_p.h
new file mode 100644 (file)
index 0000000..f060b06
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by 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 
+ * \brief private interfaces for eventlib
+ * \author vix 09sep95 [initial]
+ *
+ * $Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp $
+ */
+
+#ifndef _EVENTLIB_P_H
+#define _EVENTLIB_P_H
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/un.h>
+
+#define EVENTLIB_DEBUG 1
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef _LIBC
+#include <isc/heap.h>
+#include <isc/list.h>
+#include <isc/memcluster.h>
+#endif
+
+#define        EV_MASK_ALL     (EV_READ | EV_WRITE | EV_EXCEPT)
+#define EV_ERR(e)              return (errno = (e), -1)
+#define OK(x)          if ((x) < 0) EV_ERR(errno); else (void)NULL
+#define OKFREE(x, y)   if ((x) < 0) { FREE((y)); EV_ERR(errno); } \
+                       else (void)NULL
+
+#define        NEW(p)          if (((p) = memget(sizeof *(p))) != NULL) \
+                               FILL(p); \
+                       else \
+                               (void)NULL;
+#define OKNEW(p)       if (!((p) = memget(sizeof *(p)))) { \
+                               errno = ENOMEM; \
+                               return (-1); \
+                       } else \
+                               FILL(p)
+#define FREE(p)                memput((p), sizeof *(p))
+
+#if EVENTLIB_DEBUG
+#define FILL(p)                memset((p), 0xF5, sizeof *(p))
+#else
+#define FILL(p)
+#endif
+
+#ifdef USE_POLL
+#ifdef HAVE_STROPTS_H
+#include <stropts.h>
+#endif
+#include <poll.h>
+#endif /* USE_POLL */
+
+typedef struct evConn {
+       evConnFunc      func;
+       void *          uap;
+       int             fd;
+       int             flags;
+#define EV_CONN_LISTEN         0x0001          /*%< Connection is a listener. */
+#define EV_CONN_SELECTED       0x0002          /*%< evSelectFD(conn->file). */
+#define EV_CONN_BLOCK          0x0004          /*%< Listener fd was blocking. */
+       evFileID        file;
+       struct evConn * prev;
+       struct evConn * next;
+} evConn;
+
+#ifndef _LIBC
+typedef struct evAccept {
+       int             fd;
+       union {
+               struct sockaddr         sa;
+               struct sockaddr_in      in;
+#ifndef NO_SOCKADDR_UN
+               struct sockaddr_un      un;
+#endif
+       }               la;
+       ISC_SOCKLEN_T   lalen;
+       union {
+               struct sockaddr         sa;
+               struct sockaddr_in      in;
+#ifndef NO_SOCKADDR_UN
+               struct sockaddr_un      un;
+#endif
+       }               ra;
+       ISC_SOCKLEN_T   ralen;
+       int             ioErrno;
+       evConn *        conn;
+       LINK(struct evAccept) link;
+} evAccept;
+
+typedef struct evFile {
+       evFileFunc      func;
+       void *          uap;
+       int             fd;
+       int             eventmask;
+       int             preemptive;
+       struct evFile * prev;
+       struct evFile * next;
+       struct evFile * fdprev;
+       struct evFile * fdnext;
+} evFile;
+
+typedef struct evStream {
+       evStreamFunc    func;
+       void *          uap;
+       evFileID        file;
+       evTimerID       timer;
+       int             flags;
+#define EV_STR_TIMEROK 0x0001  /*%< IFF timer valid. */
+       int             fd;
+       struct iovec *  iovOrig;
+       int             iovOrigCount;
+       struct iovec *  iovCur;
+       int             iovCurCount;
+       int             ioTotal;
+       int             ioDone;
+       int             ioErrno;
+       struct evStream *prevDone, *nextDone;
+       struct evStream *prev, *next;
+} evStream;
+
+typedef struct evTimer {
+       evTimerFunc     func;
+       void *          uap;
+       struct timespec due, inter;
+       int             index;
+       int             mode;
+#define EV_TMR_RATE    1
+} evTimer;
+
+typedef struct evWait {
+       evWaitFunc      func;
+       void *          uap;
+       const void *    tag;
+       struct evWait * next;
+} evWait;
+
+typedef struct evWaitList {
+       evWait *                first;
+       evWait *                last;
+       struct evWaitList *     prev;
+       struct evWaitList *     next;
+} evWaitList;
+
+typedef struct evEvent_p {
+       enum {  Accept, File, Stream, Timer, Wait, Free, Null  } type;
+       union {
+               struct {  evAccept *this;  }                    accept;
+               struct {  evFile *this; int eventmask;  }       file;
+               struct {  evStream *this;  }                    stream;
+               struct {  evTimer *this;  }                     timer;
+               struct {  evWait *this;  }                      wait;
+               struct {  struct evEvent_p *next;  }            free;
+               struct {  const void *placeholder;  }           null;
+       } u;
+} evEvent_p;
+#endif /* !_LIBC */
+
+#ifdef USE_POLL
+typedef struct { 
+       void            *ctx;   /* pointer to the evContext_p   */ 
+       uint32_t        type;   /* READ, WRITE, EXCEPT, nonblk  */ 
+       uint32_t        result; /* 1 => revents, 0 => events    */ 
+} __evEmulMask; 
+
+#define emulMaskInit(ctx, field, ev, lastnext) \
+       ctx->field.ctx = ctx; \
+       ctx->field.type = ev; \
+       ctx->field.result = lastnext; 
+  
+extern short   *__fd_eventfield(int fd, __evEmulMask *maskp); 
+extern short   __poll_event(__evEmulMask *maskp); 
+extern void            __fd_clr(int fd, __evEmulMask *maskp); 
+extern void            __fd_set(int fd, __evEmulMask *maskp); 
+
+#undef  FD_ZERO 
+#define FD_ZERO(maskp) 
+  
+#undef  FD_SET 
+#define FD_SET(fd, maskp) \
+       __fd_set(fd, maskp) 
+
+#undef  FD_CLR 
+#define FD_CLR(fd, maskp) \
+       __fd_clr(fd, maskp) 
+
+#undef  FD_ISSET 
+#define FD_ISSET(fd, maskp) \
+       ((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0) 
+
+#endif /* USE_POLL */
+
+#ifndef _LIBC
+typedef struct {
+       /* Global. */
+       const evEvent_p *cur;
+       /* Debugging. */
+       int             debug;
+       FILE            *output;
+       /* Connections. */
+       evConn          *conns;
+       LIST(evAccept)  accepts;
+       /* Files. */
+       evFile          *files, *fdNext;
+#ifndef USE_POLL
+       fd_set          rdLast, rdNext;
+       fd_set          wrLast, wrNext;
+       fd_set          exLast, exNext;
+       fd_set          nonblockBefore;
+       int             fdMax, fdCount, highestFD;
+       evFile          *fdTable[FD_SETSIZE];
+#else
+       struct pollfd   *pollfds;       /* Allocated as needed  */ 
+       evFile          **fdTable;      /* Ditto                */ 
+       int             maxnfds;        /* # elements in above  */ 
+       int             firstfd;        /* First active fd      */ 
+       int             fdMax;          /* Last active fd       */ 
+       int             fdCount;        /* # fd:s with I/O      */ 
+       int             highestFD;      /* max fd allowed by OS */ 
+       __evEmulMask    rdLast, rdNext; 
+       __evEmulMask    wrLast, wrNext; 
+       __evEmulMask    exLast, exNext; 
+       __evEmulMask    nonblockBefore; 
+#endif /* USE_POLL */
+#ifdef EVENTLIB_TIME_CHECKS
+       struct timespec lastSelectTime;
+       int             lastFdCount;
+#endif
+       /* Streams. */
+       evStream        *streams;
+       evStream        *strDone, *strLast;
+       /* Timers. */
+       struct timespec lastEventTime;
+       heap_context    timers;
+       /* Waits. */
+       evWaitList      *waitLists;
+       evWaitList      waitDone;
+} evContext_p;
+
+/* eventlib.c */
+#define evPrintf __evPrintf
+void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...)
+     ISC_FORMAT_PRINTF(3, 4);
+
+#ifdef USE_POLL
+extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd);
+#endif /* USE_POLL */
+
+/* ev_timers.c */
+#define evCreateTimers __evCreateTimers
+heap_context evCreateTimers(const evContext_p *);
+#define evDestroyTimers __evDestroyTimers
+void evDestroyTimers(const evContext_p *);
+
+/* ev_waits.c */
+#define evFreeWait __evFreeWait
+evWait *evFreeWait(evContext_p *ctx, evWait *old);
+#endif /* !_LIBC */
+
+/* Global options */
+#ifndef _LIBC
+extern int     __evOptMonoTime;
+#endif /* !_LIBC */
+
+#endif /*_EVENTLIB_P_H*/
diff --git a/lib/libc/nameser/ns_name.c b/lib/libc/nameser/ns_name.c
new file mode 100644 (file)
index 0000000..9d409f3
--- /dev/null
@@ -0,0 +1,973 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by 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 lint
+static const char rcsid[] = "$Id: ns_name.c,v 1.10 2005/04/27 04:56:40 sra Exp $";
+#endif
+
+#include "port_before.h"
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <limits.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+#define NS_TYPE_ELT                    0x40 /*%< EDNS0 extended label type */
+#define DNS_LABELTYPE_BITSTRING                0x41
+
+/* Data. */
+
+static const char      digits[] = "0123456789";
+
+static const char digitvalue[256] = {
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*16*/
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*32*/
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*48*/
+        0,  1,  2,  3,  4,  5,  6,  7,  8,  9, -1, -1, -1, -1, -1, -1, /*64*/
+       -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*80*/
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*96*/
+       -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*112*/
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*128*/
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+       -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /*256*/
+};
+
+/* Forward. */
+
+static int             special(int);
+static int             printable(int);
+static int             dn_find(const u_char *, const u_char *,
+                               const u_char * const *,
+                               const u_char * const *);
+static int             encode_bitsring(const char **, const char *,
+                                       unsigned char **, unsigned char **,
+                                       unsigned const char *);
+static int             labellen(const u_char *);
+static int             decode_bitstring(const unsigned char **,
+                                        char *, const char *);
+
+/* Public. */
+
+/*%
+ *     Convert an encoded domain name to printable ascii as per RFC1035.
+
+ * return:
+ *\li  Number of bytes written to buffer, or -1 (with errno set)
+ *
+ * notes:
+ *\li  The root is returned as "."
+ *\li  All other domains are returned in non absolute form
+ */
+int
+ns_name_ntop(const u_char *src, char *dst, size_t dstsiz)
+{
+       const u_char *cp;
+       char *dn, *eom;
+       u_char c;
+       u_int n;
+       int l;
+
+       cp = src;
+       dn = dst;
+       eom = dst + dstsiz;
+
+       while ((n = *cp++) != 0) {
+               if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+                       /* Some kind of compression pointer. */
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               if (dn != dst) {
+                       if (dn >= eom) {
+                               errno = EMSGSIZE;
+                               return (-1);
+                       }
+                       *dn++ = '.';
+               }
+               if ((l = labellen(cp - 1)) < 0) {
+                       errno = EMSGSIZE; /*%< XXX */
+                       return(-1);
+               }
+               if (dn + l >= eom) {
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               if ((n & NS_CMPRSFLGS) == NS_TYPE_ELT) {
+                       int m;
+
+                       if (n != DNS_LABELTYPE_BITSTRING) {
+                               /* XXX: labellen should reject this case */
+                               errno = EINVAL;
+                               return(-1);
+                       }
+                       if ((m = decode_bitstring(&cp, dn, eom)) < 0)
+                       {
+                               errno = EMSGSIZE;
+                               return(-1);
+                       }
+                       dn += m; 
+                       continue;
+               }
+               for ((void)NULL; l > 0; l--) {
+                       c = *cp++;
+                       if (special(c)) {
+                               if (dn + 1 >= eom) {
+                                       errno = EMSGSIZE;
+                                       return (-1);
+                               }
+                               *dn++ = '\\';
+                               *dn++ = (char)c;
+                       } else if (!printable(c)) {
+                               if (dn + 3 >= eom) {
+                                       errno = EMSGSIZE;
+                                       return (-1);
+                               }
+                               *dn++ = '\\';
+                               *dn++ = digits[c / 100];
+                               *dn++ = digits[(c % 100) / 10];
+                               *dn++ = digits[c % 10];
+                       } else {
+                               if (dn >= eom) {
+                                       errno = EMSGSIZE;
+                                       return (-1);
+                               }
+                               *dn++ = (char)c;
+                       }
+               }
+       }
+       if (dn == dst) {
+               if (dn >= eom) {
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               *dn++ = '.';
+       }
+       if (dn >= eom) {
+               errno = EMSGSIZE;
+               return (-1);
+       }
+       *dn++ = '\0';
+       return (dn - dst);
+}
+
+/*%
+ *     Convert a ascii string into an encoded domain name as per RFC1035.
+ *
+ * return:
+ *
+ *\li  -1 if it fails
+ *\li  1 if string was fully qualified
+ *\li  0 is string was not fully qualified
+ *
+ * notes:
+ *\li  Enforces label and domain length limits.
+ */
+
+int
+ns_name_pton(const char *src, u_char *dst, size_t dstsiz)
+{
+       u_char *label, *bp, *eom;
+       int c, n, escaped, e = 0;
+       char *cp;
+
+       escaped = 0;
+       bp = dst;
+       eom = dst + dstsiz;
+       label = bp++;
+
+       while ((c = *src++) != 0) {
+               if (escaped) {
+                       if (c == '[') { /*%< start a bit string label */
+                               if ((cp = strchr(src, ']')) == NULL) {
+                                       errno = EINVAL; /*%< ??? */
+                                       return(-1);
+                               }
+                               if ((e = encode_bitsring(&src, cp + 2,
+                                                        &label, &bp, eom))
+                                   != 0) {
+                                       errno = e;
+                                       return(-1);
+                               }
+                               escaped = 0;
+                               label = bp++;
+                               if ((c = *src++) == 0)
+                                       goto done;
+                               else if (c != '.') {
+                                       errno = EINVAL;
+                                       return(-1);
+                               }
+                               continue;
+                       }
+                       else if ((cp = strchr(digits, c)) != NULL) {
+                               n = (cp - digits) * 100;
+                               if ((c = *src++) == 0 ||
+                                   (cp = strchr(digits, c)) == NULL) {
+                                       errno = EMSGSIZE;
+                                       return (-1);
+                               }
+                               n += (cp - digits) * 10;
+                               if ((c = *src++) == 0 ||
+                                   (cp = strchr(digits, c)) == NULL) {
+                                       errno = EMSGSIZE;
+                                       return (-1);
+                               }
+                               n += (cp - digits);
+                               if (n > 255) {
+                                       errno = EMSGSIZE;
+                                       return (-1);
+                               }
+                               c = n;
+                       }
+                       escaped = 0;
+               } else if (c == '\\') {
+                       escaped = 1;
+                       continue;
+               } else if (c == '.') {
+                       c = (bp - label - 1);
+                       if ((c & NS_CMPRSFLGS) != 0) {  /*%< Label too big. */
+                               errno = EMSGSIZE;
+                               return (-1);
+                       }
+                       if (label >= eom) {
+                               errno = EMSGSIZE;
+                               return (-1);
+                       }
+                       *label = c;
+                       /* Fully qualified ? */
+                       if (*src == '\0') {
+                               if (c != 0) {
+                                       if (bp >= eom) {
+                                               errno = EMSGSIZE;
+                                               return (-1);
+                                       }
+                                       *bp++ = '\0';
+                               }
+                               if ((bp - dst) > MAXCDNAME) {
+                                       errno = EMSGSIZE;
+                                       return (-1);
+                               }
+                               return (1);
+                       }
+                       if (c == 0 || *src == '.') {
+                               errno = EMSGSIZE;
+                               return (-1);
+                       }
+                       label = bp++;
+                       continue;
+               }
+               if (bp >= eom) {
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               *bp++ = (u_char)c;
+       }
+       c = (bp - label - 1);
+       if ((c & NS_CMPRSFLGS) != 0) {          /*%< Label too big. */
+               errno = EMSGSIZE;
+               return (-1);
+       }
+  done:
+       if (label >= eom) {
+               errno = EMSGSIZE;
+               return (-1);
+       }
+       *label = c;
+       if (c != 0) {
+               if (bp >= eom) {
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               *bp++ = 0;
+       }
+       if ((bp - dst) > MAXCDNAME) {   /*%< src too big */
+               errno = EMSGSIZE;
+               return (-1);
+       }
+       return (0);
+}
+
+/*%
+ *     Convert a network strings labels into all lowercase.
+ *
+ * return:
+ *\li  Number of bytes written to buffer, or -1 (with errno set)
+ *
+ * notes:
+ *\li  Enforces label and domain length limits.
+ */
+
+int
+ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz)
+{
+       const u_char *cp;
+       u_char *dn, *eom;
+       u_char c;
+       u_int n;
+       int l;
+
+       cp = src;
+       dn = dst;
+       eom = dst + dstsiz;
+
+       if (dn >= eom) {
+               errno = EMSGSIZE;
+               return (-1);
+       }
+       while ((n = *cp++) != 0) {
+               if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+                       /* Some kind of compression pointer. */
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               *dn++ = n;
+               if ((l = labellen(cp - 1)) < 0) {
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               if (dn + l >= eom) {
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               for ((void)NULL; l > 0; l--) {
+                       c = *cp++;
+                       if (isupper(c))
+                               *dn++ = tolower(c);
+                       else
+                               *dn++ = c;
+               }
+       }
+       *dn++ = '\0';
+       return (dn - dst);
+}
+
+/*%
+ *     Unpack a domain name from a message, source may be compressed.
+ *
+ * return:
+ *\li  -1 if it fails, or consumed octets if it succeeds.
+ */
+int
+ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
+              u_char *dst, size_t dstsiz)
+{
+       const u_char *srcp, *dstlim;
+       u_char *dstp;
+       int n, len, checked, l;
+
+       len = -1;
+       checked = 0;
+       dstp = dst;
+       srcp = src;
+       dstlim = dst + dstsiz;
+       if (srcp < msg || srcp >= eom) {
+               errno = EMSGSIZE;
+               return (-1);
+       }
+       /* Fetch next label in domain name. */
+       while ((n = *srcp++) != 0) {
+               /* Check for indirection. */
+               switch (n & NS_CMPRSFLGS) {
+               case 0:
+               case NS_TYPE_ELT:
+                       /* Limit checks. */
+                       if ((l = labellen(srcp - 1)) < 0) {
+                               errno = EMSGSIZE;
+                               return(-1);
+                       }
+                       if (dstp + l + 1 >= dstlim || srcp + l >= eom) {
+                               errno = EMSGSIZE;
+                               return (-1);
+                       }
+                       checked += l + 1;
+                       *dstp++ = n;
+                       memcpy(dstp, srcp, l);
+                       dstp += l;
+                       srcp += l;
+                       break;
+
+               case NS_CMPRSFLGS:
+                       if (srcp >= eom) {
+                               errno = EMSGSIZE;
+                               return (-1);
+                       }
+                       if (len < 0)
+                               len = srcp - src + 1;
+                       srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
+                       if (srcp < msg || srcp >= eom) {  /*%< Out of range. */
+                               errno = EMSGSIZE;
+                               return (-1);
+                       }
+                       checked += 2;
+                       /*
+                        * Check for loops in the compressed name;
+                        * if we've looked at the whole message,
+                        * there must be a loop.
+                        */
+                       if (checked >= eom - msg) {
+                               errno = EMSGSIZE;
+                               return (-1);
+                       }
+                       break;
+
+               default:
+                       errno = EMSGSIZE;
+                       return (-1);                    /*%< flag error */
+               }
+       }
+       *dstp = '\0';
+       if (len < 0)
+               len = srcp - src;
+       return (len);
+}
+
+/*%
+ *     Pack domain name 'domain' into 'comp_dn'.
+ *
+ * return:
+ *\li  Size of the compressed name, or -1.
+ *
+ * notes:
+ *\li  'dnptrs' is an array of pointers to previous compressed names.
+ *\li  dnptrs[0] is a pointer to the beginning of the message. The array
+ *     ends with NULL.
+ *\li  'lastdnptr' is a pointer to the end of the array pointed to
+ *     by 'dnptrs'.
+ *
+ * Side effects:
+ *\li  The list of pointers in dnptrs is updated for labels inserted into
+ *     the message as we compress the name.  If 'dnptr' is NULL, we don't
+ *     try to compress names. If 'lastdnptr' is NULL, we don't update the
+ *     list.
+ */
+int
+ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
+            const u_char **dnptrs, const u_char **lastdnptr)
+{
+       u_char *dstp;
+       const u_char **cpp, **lpp, *eob, *msg;
+       const u_char *srcp;
+       int n, l, first = 1;
+
+       srcp = src;
+       dstp = dst;
+       eob = dstp + dstsiz;
+       lpp = cpp = NULL;
+       if (dnptrs != NULL) {
+               if ((msg = *dnptrs++) != NULL) {
+                       for (cpp = dnptrs; *cpp != NULL; cpp++)
+                               (void)NULL;
+                       lpp = cpp;      /*%< end of list to search */
+               }
+       } else
+               msg = NULL;
+
+       /* make sure the domain we are about to add is legal */
+       l = 0;
+       do {
+               int l0;
+
+               n = *srcp;
+               if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               if ((l0 = labellen(srcp)) < 0) {
+                       errno = EINVAL;
+                       return(-1);
+               }
+               l += l0 + 1;
+               if (l > MAXCDNAME) {
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               srcp += l0 + 1;
+       } while (n != 0);
+
+       /* from here on we need to reset compression pointer array on error */
+       srcp = src;
+       do {
+               /* Look to see if we can use pointers. */
+               n = *srcp;
+               if (n != 0 && msg != NULL) {
+                       l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
+                                   (const u_char * const *)lpp);
+                       if (l >= 0) {
+                               if (dstp + 1 >= eob) {
+                                       goto cleanup;
+                               }
+                               *dstp++ = (l >> 8) | NS_CMPRSFLGS;
+                               *dstp++ = l % 256;
+                               return (dstp - dst);
+                       }
+                       /* Not found, save it. */
+                       if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
+                           (dstp - msg) < 0x4000 && first) {
+                               *cpp++ = dstp;
+                               *cpp = NULL;
+                               first = 0;
+                       }
+               }
+               /* copy label to buffer */
+               if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+                       /* Should not happen. */
+                       goto cleanup;
+               }
+               n = labellen(srcp);
+               if (dstp + 1 + n >= eob) {
+                       goto cleanup;
+               }
+               memcpy(dstp, srcp, n + 1);
+               srcp += n + 1;
+               dstp += n + 1;
+       } while (n != 0);
+
+       if (dstp > eob) {
+cleanup:
+               if (msg != NULL)
+                       *lpp = NULL;
+               errno = EMSGSIZE;
+               return (-1);
+       } 
+       return (dstp - dst);
+}
+
+/*%
+ *     Expand compressed domain name to presentation format.
+ *
+ * return:
+ *\li  Number of bytes read out of `src', or -1 (with errno set).
+ *
+ * note:
+ *\li  Root domain returns as "." not "".
+ */
+int
+ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
+                  char *dst, size_t dstsiz)
+{
+       u_char tmp[NS_MAXCDNAME];
+       int n;
+       
+       if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
+               return (-1);
+       if (ns_name_ntop(tmp, dst, dstsiz) == -1)
+               return (-1);
+       return (n);
+}
+
+/*%
+ *     Compress a domain name into wire format, using compression pointers.
+ *
+ * return:
+ *\li  Number of bytes consumed in `dst' or -1 (with errno set).
+ *
+ * notes:
+ *\li  'dnptrs' is an array of pointers to previous compressed names.
+ *\li  dnptrs[0] is a pointer to the beginning of the message.
+ *\li  The list ends with NULL.  'lastdnptr' is a pointer to the end of the
+ *     array pointed to by 'dnptrs'. Side effect is to update the list of
+ *     pointers for labels inserted into the message as we compress the name.
+ *\li  If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
+ *     is NULL, we don't update the list.
+ */
+int
+ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
+                const u_char **dnptrs, const u_char **lastdnptr)
+{
+       u_char tmp[NS_MAXCDNAME];
+
+       if (ns_name_pton(src, tmp, sizeof tmp) == -1)
+               return (-1);
+       return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
+}
+
+/*%
+ * Reset dnptrs so that there are no active references to pointers at or
+ * after src.
+ */
+void
+ns_name_rollback(const u_char *src, const u_char **dnptrs,
+                const u_char **lastdnptr)
+{
+       while (dnptrs < lastdnptr && *dnptrs != NULL) {
+               if (*dnptrs >= src) {
+                       *dnptrs = NULL;
+                       break;
+               }
+               dnptrs++;
+       }
+}
+
+/*%
+ *     Advance *ptrptr to skip over the compressed name it points at.
+ *
+ * return:
+ *\li  0 on success, -1 (with errno set) on failure.
+ */
+int
+ns_name_skip(const u_char **ptrptr, const u_char *eom)
+{
+       const u_char *cp;
+       u_int n;
+       int l;
+
+       cp = *ptrptr;
+       while (cp < eom && (n = *cp++) != 0) {
+               /* Check for indirection. */
+               switch (n & NS_CMPRSFLGS) {
+               case 0:                 /*%< normal case, n == len */
+                       cp += n;
+                       continue;
+               case NS_TYPE_ELT: /*%< EDNS0 extended label */
+                       if ((l = labellen(cp - 1)) < 0) {
+                               errno = EMSGSIZE; /*%< XXX */
+                               return(-1);
+                       }
+                       cp += l;
+                       continue;
+               case NS_CMPRSFLGS:      /*%< indirection */
+                       cp++;
+                       break;
+               default:                /*%< illegal type */
+                       errno = EMSGSIZE;
+                       return (-1);
+               }
+               break;
+       }
+       if (cp > eom) {
+               errno = EMSGSIZE;
+               return (-1);
+       }
+       *ptrptr = cp;
+       return (0);
+}
+
+/* Private. */
+
+/*%
+ *     Thinking in noninternationalized USASCII (per the DNS spec),
+ *     is this characted special ("in need of quoting") ?
+ *
+ * return:
+ *\li  boolean.
+ */
+static int
+special(int ch) {
+       switch (ch) {
+       case 0x22: /*%< '"' */
+       case 0x2E: /*%< '.' */
+       case 0x3B: /*%< ';' */
+       case 0x5C: /*%< '\\' */
+       case 0x28: /*%< '(' */
+       case 0x29: /*%< ')' */
+       /* Special modifiers in zone files. */
+       case 0x40: /*%< '@' */
+       case 0x24: /*%< '$' */
+               return (1);
+       default:
+               return (0);
+       }
+}
+
+/*%
+ *     Thinking in noninternationalized USASCII (per the DNS spec),
+ *     is this character visible and not a space when printed ?
+ *
+ * return:
+ *\li  boolean.
+ */
+static int
+printable(int ch) {
+       return (ch > 0x20 && ch < 0x7f);
+}
+
+/*%
+ *     Thinking in noninternationalized USASCII (per the DNS spec),
+ *     convert this character to lower case if it's upper case.
+ */
+static int
+mklower(int ch) {
+       if (ch >= 0x41 && ch <= 0x5A)
+               return (ch + 0x20);
+       return (ch);
+}
+
+/*%
+ *     Search for the counted-label name in an array of compressed names.
+ *
+ * return:
+ *\li  offset from msg if found, or -1.
+ *
+ * notes:
+ *\li  dnptrs is the pointer to the first name on the list,
+ *\li  not the pointer to the start of the message.
+ */
+static int
+dn_find(const u_char *domain, const u_char *msg,
+       const u_char * const *dnptrs,
+       const u_char * const *lastdnptr)
+{
+       const u_char *dn, *cp, *sp;
+       const u_char * const *cpp;
+       u_int n;
+
+       for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
+               sp = *cpp;
+               /*
+                * terminate search on:
+                * root label
+                * compression pointer
+                * unusable offset
+                */
+               while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
+                      (sp - msg) < 0x4000) {
+                       dn = domain;
+                       cp = sp;
+                       while ((n = *cp++) != 0) {
+                               /*
+                                * check for indirection
+                                */
+                               switch (n & NS_CMPRSFLGS) {
+                               case 0:         /*%< normal case, n == len */
+                                       n = labellen(cp - 1); /*%< XXX */
+                                       if (n != *dn++)
+                                               goto next;
+
+                                       for ((void)NULL; n > 0; n--)
+                                               if (mklower(*dn++) !=
+                                                   mklower(*cp++))
+                                                       goto next;
+                                       /* Is next root for both ? */
+                                       if (*dn == '\0' && *cp == '\0')
+                                               return (sp - msg);
+                                       if (*dn)
+                                               continue;
+                                       goto next;
+                               case NS_CMPRSFLGS:      /*%< indirection */
+                                       cp = msg + (((n & 0x3f) << 8) | *cp);
+                                       break;
+
+                               default:        /*%< illegal type */
+                                       errno = EMSGSIZE;
+                                       return (-1);
+                               }
+                       }
+ next: ;
+                       sp += *sp + 1;
+               }
+       }
+       errno = ENOENT;
+       return (-1);
+}
+
+static int
+decode_bitstring(const unsigned char **cpp, char *dn, const char *eom)
+{
+       const unsigned char *cp = *cpp;
+       char *beg = dn, tc;
+       int b, blen, plen, i;
+
+       if ((blen = (*cp & 0xff)) == 0)
+               blen = 256;
+       plen = (blen + 3) / 4;
+       plen += sizeof("\\[x/]") + (blen > 99 ? 3 : (blen > 9) ? 2 : 1);
+       if (dn + plen >= eom)
+               return(-1);
+
+       cp++;
+       i = SPRINTF((dn, "\\[x"));
+       if (i < 0)
+               return (-1);
+       dn += i;
+       for (b = blen; b > 7; b -= 8, cp++) {
+               i = SPRINTF((dn, "%02x", *cp & 0xff));
+               if (i < 0)
+                       return (-1);
+               dn += i;
+       }
+       if (b > 4) {
+               tc = *cp++;
+               i = SPRINTF((dn, "%02x", tc & (0xff << (8 - b))));
+               if (i < 0)
+                       return (-1);
+               dn += i;
+       } else if (b > 0) {
+               tc = *cp++;
+               i = SPRINTF((dn, "%1x",
+                              ((tc >> 4) & 0x0f) & (0x0f << (4 - b)))); 
+               if (i < 0)
+                       return (-1);
+               dn += i;
+       }
+       i = SPRINTF((dn, "/%d]", blen));
+       if (i < 0)
+               return (-1);
+       dn += i;
+
+       *cpp = cp;
+       return(dn - beg);
+}
+
+static int
+encode_bitsring(const char **bp, const char *end, unsigned char **labelp,
+               unsigned char ** dst, unsigned const char *eom)
+{
+       int afterslash = 0;
+       const char *cp = *bp;
+       unsigned char *tp;
+       char c;
+       const char *beg_blen;
+       char *end_blen = NULL;
+       int value = 0, count = 0, tbcount = 0, blen = 0;
+
+       beg_blen = end_blen = NULL;
+
+       /* a bitstring must contain at least 2 characters */
+       if (end - cp < 2)
+               return(EINVAL);
+
+       /* XXX: currently, only hex strings are supported */
+       if (*cp++ != 'x')
+               return(EINVAL);
+       if (!isxdigit((*cp) & 0xff)) /*%< reject '\[x/BLEN]' */
+               return(EINVAL);
+
+       for (tp = *dst + 1; cp < end && tp < eom; cp++) {
+               switch((c = *cp)) {
+               case ']':       /*%< end of the bitstring */
+                       if (afterslash) {
+                               if (beg_blen == NULL)
+                                       return(EINVAL);
+                               blen = (int)strtol(beg_blen, &end_blen, 10);
+                               if (*end_blen != ']')
+                                       return(EINVAL);
+                       }
+                       if (count)
+                               *tp++ = ((value << 4) & 0xff);
+                       cp++;   /*%< skip ']' */
+                       goto done;
+               case '/':
+                       afterslash = 1;
+                       break;
+               default:
+                       if (afterslash) {
+                               if (!isdigit(c&0xff))
+                                       return(EINVAL);
+                               if (beg_blen == NULL) {
+                                       
+                                       if (c == '0') {
+                                               /* blen never begings with 0 */
+                                               return(EINVAL);
+                                       }
+                                       beg_blen = cp;
+                               }
+                       } else {
+                               if (!isxdigit(c&0xff))
+                                       return(EINVAL);
+                               value <<= 4;
+                               value += digitvalue[(int)c];
+                               count += 4;
+                               tbcount += 4;
+                               if (tbcount > 256)
+                                       return(EINVAL);
+                               if (count == 8) {
+                                       *tp++ = value;
+                                       count = 0;
+                               }
+                       }
+                       break;
+               }
+       }
+  done:
+       if (cp >= end || tp >= eom)
+               return(EMSGSIZE);
+
+       /*
+        * bit length validation:
+        * If a <length> is present, the number of digits in the <bit-data>
+        * MUST be just sufficient to contain the number of bits specified
+        * by the <length>. If there are insignificant bits in a final
+        * hexadecimal or octal digit, they MUST be zero.
+        * RFC2673, Section 3.2.
+        */
+       if (blen > 0) {
+               int traillen;
+
+               if (((blen + 3) & ~3) != tbcount)
+                       return(EINVAL);
+               traillen = tbcount - blen; /*%< between 0 and 3 */
+               if (((value << (8 - traillen)) & 0xff) != 0)
+                       return(EINVAL);
+       }
+       else
+               blen = tbcount;
+       if (blen == 256)
+               blen = 0;
+
+       /* encode the type and the significant bit fields */
+       **labelp = DNS_LABELTYPE_BITSTRING;
+       **dst = blen;
+
+       *bp = cp;
+       *dst = tp;
+
+       return(0);
+}
+
+static int
+labellen(const u_char *lp)
+{
+       int bitlen;
+       u_char l = *lp;
+
+       if ((l & NS_CMPRSFLGS) == NS_CMPRSFLGS) {
+               /* should be avoided by the caller */
+               return(-1);
+       }
+
+       if ((l & NS_CMPRSFLGS) == NS_TYPE_ELT) {
+               if (l == DNS_LABELTYPE_BITSTRING) {
+                       if ((bitlen = *(lp + 1)) == 0)
+                               bitlen = 256;
+                       return((bitlen + 7 ) / 8 + 1);
+               }
+               return(-1);     /*%< unknwon ELT */
+       }
+       return(l);
+}
+
+/*! \file */
diff --git a/lib/libc/nameser/ns_netint.c b/lib/libc/nameser/ns_netint.c
new file mode 100644 (file)
index 0000000..559c9d5
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by 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 lint
+static const char rcsid[] = "$Id: ns_netint.c,v 1.3 2005/04/27 04:56:40 sra Exp $";
+#endif
+
+/* Import. */
+
+#include "port_before.h"
+
+#include <arpa/nameser.h>
+
+#include "port_after.h"
+
+/* Public. */
+
+u_int
+ns_get16(const u_char *src) {
+       u_int dst;
+
+       NS_GET16(dst, src);
+       return (dst);
+}
+
+u_long
+ns_get32(const u_char *src) {
+       u_long dst;
+
+       NS_GET32(dst, src);
+       return (dst);
+}
+
+void
+ns_put16(u_int src, u_char *dst) {
+       NS_PUT16(src, dst);
+}
+
+void
+ns_put32(u_long src, u_char *dst) {
+       NS_PUT32(src, dst);
+}
+
+/*! \file */
diff --git a/lib/libc/nameser/ns_parse.c b/lib/libc/nameser/ns_parse.c
new file mode 100644 (file)
index 0000000..09b19f8
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by 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 lint
+static const char rcsid[] = "$Id: ns_parse.c,v 1.9 2007/08/27 03:32:26 marka Exp $";
+#endif
+
+/* Import. */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+
+#include "port_after.h"
+
+/* Forward. */
+
+static void    setsection(ns_msg *msg, ns_sect sect);
+
+/* Macros. */
+
+#if !defined(SOLARIS2) || defined(__COVERITY__)
+#define RETERR(err) do { errno = (err); return (-1); } while (0)
+#else
+#define RETERR(err) \
+       do { errno = (err); if (errno == errno) return (-1); } while (0)
+#endif
+
+/* Public. */
+
+/* These need to be in the same order as the nres.h:ns_flag enum. */
+struct _ns_flagdata _ns_flagdata[16] = {
+       { 0x8000, 15 },         /*%< qr. */
+       { 0x7800, 11 },         /*%< opcode. */
+       { 0x0400, 10 },         /*%< aa. */
+       { 0x0200, 9 },          /*%< tc. */
+       { 0x0100, 8 },          /*%< rd. */
+       { 0x0080, 7 },          /*%< ra. */
+       { 0x0040, 6 },          /*%< z. */
+       { 0x0020, 5 },          /*%< ad. */
+       { 0x0010, 4 },          /*%< cd. */
+       { 0x000f, 0 },          /*%< rcode. */
+       { 0x0000, 0 },          /*%< expansion (1/6). */
+       { 0x0000, 0 },          /*%< expansion (2/6). */
+       { 0x0000, 0 },          /*%< expansion (3/6). */
+       { 0x0000, 0 },          /*%< expansion (4/6). */
+       { 0x0000, 0 },          /*%< expansion (5/6). */
+       { 0x0000, 0 },          /*%< expansion (6/6). */
+};
+
+int ns_msg_getflag(ns_msg handle, int flag) {
+       return(((handle)._flags & _ns_flagdata[flag].mask) >> _ns_flagdata[flag].shift);
+}
+
+int
+ns_skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
+       const u_char *optr = ptr;
+
+       for ((void)NULL; count > 0; count--) {
+               int b, rdlength;
+
+               b = dn_skipname(ptr, eom);
+               if (b < 0)
+                       RETERR(EMSGSIZE);
+               ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
+               if (section != ns_s_qd) {
+                       if (ptr + NS_INT32SZ + NS_INT16SZ > eom)
+                               RETERR(EMSGSIZE);
+                       ptr += NS_INT32SZ/*TTL*/;
+                       NS_GET16(rdlength, ptr);
+                       ptr += rdlength/*RData*/;
+               }
+       }
+       if (ptr > eom)
+               RETERR(EMSGSIZE);
+       return (ptr - optr);
+}
+
+int
+ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
+       const u_char *eom = msg + msglen;
+       int i;
+
+       memset(handle, 0x5e, sizeof *handle);
+       handle->_msg = msg;
+       handle->_eom = eom;
+       if (msg + NS_INT16SZ > eom)
+               RETERR(EMSGSIZE);
+       NS_GET16(handle->_id, msg);
+       if (msg + NS_INT16SZ > eom)
+               RETERR(EMSGSIZE);
+       NS_GET16(handle->_flags, msg);
+       for (i = 0; i < ns_s_max; i++) {
+               if (msg + NS_INT16SZ > eom)
+                       RETERR(EMSGSIZE);
+               NS_GET16(handle->_counts[i], msg);
+       }
+       for (i = 0; i < ns_s_max; i++)
+               if (handle->_counts[i] == 0)
+                       handle->_sections[i] = NULL;
+               else {
+                       int b = ns_skiprr(msg, eom, (ns_sect)i,
+                                         handle->_counts[i]);
+
+                       if (b < 0)
+                               return (-1);
+                       handle->_sections[i] = msg;
+                       msg += b;
+               }
+       if (msg != eom)
+               RETERR(EMSGSIZE);
+       setsection(handle, ns_s_max);
+       return (0);
+}
+
+int
+ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
+       int b;
+       int tmp;
+
+       /* Make section right. */
+       tmp = section;
+       if (tmp < 0 || section >= ns_s_max)
+               RETERR(ENODEV);
+       if (section != handle->_sect)
+               setsection(handle, section);
+
+       /* Make rrnum right. */
+       if (rrnum == -1)
+               rrnum = handle->_rrnum;
+       if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
+               RETERR(ENODEV);
+       if (rrnum < handle->_rrnum)
+               setsection(handle, section);
+       if (rrnum > handle->_rrnum) {
+               b = ns_skiprr(handle->_msg_ptr, handle->_eom, section,
+                             rrnum - handle->_rrnum);
+
+               if (b < 0)
+                       return (-1);
+               handle->_msg_ptr += b;
+               handle->_rrnum = rrnum;
+       }
+
+       /* Do the parse. */
+       b = dn_expand(handle->_msg, handle->_eom,
+                     handle->_msg_ptr, rr->name, NS_MAXDNAME);
+       if (b < 0)
+               return (-1);
+       handle->_msg_ptr += b;
+       if (handle->_msg_ptr + NS_INT16SZ + NS_INT16SZ > handle->_eom)
+               RETERR(EMSGSIZE);
+       NS_GET16(rr->type, handle->_msg_ptr);
+       NS_GET16(rr->rr_class, handle->_msg_ptr);
+       if (section == ns_s_qd) {
+               rr->ttl = 0;
+               rr->rdlength = 0;
+               rr->rdata = NULL;
+       } else {
+               if (handle->_msg_ptr + NS_INT32SZ + NS_INT16SZ > handle->_eom)
+                       RETERR(EMSGSIZE);
+               NS_GET32(rr->ttl, handle->_msg_ptr);
+               NS_GET16(rr->rdlength, handle->_msg_ptr);
+               if (handle->_msg_ptr + rr->rdlength > handle->_eom)
+                       RETERR(EMSGSIZE);
+               rr->rdata = handle->_msg_ptr;
+               handle->_msg_ptr += rr->rdlength;
+       }
+       if (++handle->_rrnum > handle->_counts[(int)section])
+               setsection(handle, (ns_sect)((int)section + 1));
+
+       /* All done. */
+       return (0);
+}
+
+/* Private. */
+
+static void
+setsection(ns_msg *msg, ns_sect sect) {
+       msg->_sect = sect;
+       if (sect == ns_s_max) {
+               msg->_rrnum = -1;
+               msg->_msg_ptr = NULL;
+       } else {
+               msg->_rrnum = 0;
+               msg->_msg_ptr = msg->_sections[(int)sect];
+       }
+}
+
+/*! \file */
diff --git a/lib/libc/nameser/ns_print.c b/lib/libc/nameser/ns_print.c
new file mode 100644 (file)
index 0000000..4dc20dc
--- /dev/null
@@ -0,0 +1,906 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996-1999 by 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 lint
+static const char rcsid[] = "$Id: ns_print.c,v 1.10 2005/04/27 04:56:40 sra Exp $";
+#endif
+
+/* Import. */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#ifdef _LIBC
+#include <assert.h>
+#define INSIST(cond)   assert(cond)
+#else
+#include <isc/assertions.h>
+#include <isc/dst.h>
+#endif
+#include <errno.h>
+#include <resolv.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/* Forward. */
+
+static size_t  prune_origin(const char *name, const char *origin);
+static int     charstr(const u_char *rdata, const u_char *edata,
+                       char **buf, size_t *buflen);
+static int     addname(const u_char *msg, size_t msglen,
+                       const u_char **p, const char *origin,
+                       char **buf, size_t *buflen);
+static void    addlen(size_t len, char **buf, size_t *buflen);
+static int     addstr(const char *src, size_t len,
+                      char **buf, size_t *buflen);
+static int     addtab(size_t len, size_t target, int spaced,
+                      char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define        T(x) \
+       do { \
+               if ((x) < 0) \
+                       return (-1); \
+       } while (0)
+
+/* Public. */
+
+/*%
+ *     Convert an RR to presentation format.
+ *
+ * return:
+ *\li  Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
+           const char *name_ctx, const char *origin,
+           char *buf, size_t buflen)
+{
+       int n;
+
+       n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
+                        ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
+                        ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
+                        name_ctx, origin, buf, buflen);
+       return (n);
+}
+
+/*%
+ *     Convert the fields of an RR into presentation format.
+ *
+ * return:
+ *\li  Number of characters written to buf, or -1 (check errno).
+ */
+int
+ns_sprintrrf(const u_char *msg, size_t msglen,
+           const char *name, ns_class class, ns_type type,
+           u_long ttl, const u_char *rdata, size_t rdlen,
+           const char *name_ctx, const char *origin,
+           char *buf, size_t buflen)
+{
+       const char *obuf = buf;
+       const u_char *edata = rdata + rdlen;
+       int spaced = 0;
+
+       const char *comment;
+       char tmp[100];
+       int len, x;
+
+       /*
+        * Owner.
+        */
+       if (name_ctx != NULL && ns_samename(name_ctx, name) == 1) {
+               T(addstr("\t\t\t", 3, &buf, &buflen));
+       } else {
+               len = prune_origin(name, origin);
+               if (*name == '\0') {
+                       goto root;
+               } else if (len == 0) {
+                       T(addstr("@\t\t\t", 4, &buf, &buflen));
+               } else {
+                       T(addstr(name, len, &buf, &buflen));
+                       /* Origin not used or not root, and no trailing dot? */
+                       if (((origin == NULL || origin[0] == '\0') ||
+                           (origin[0] != '.' && origin[1] != '\0' &&
+                           name[len] == '\0')) && name[len - 1] != '.') {
+ root:
+                               T(addstr(".", 1, &buf, &buflen));
+                               len++;
+                       }
+                       T(spaced = addtab(len, 24, spaced, &buf, &buflen));
+               }
+       }
+
+       /*
+        * TTL, Class, Type.
+        */
+       T(x = ns_format_ttl(ttl, buf, buflen));
+       addlen(x, &buf, &buflen);
+       len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
+       T(addstr(tmp, len, &buf, &buflen));
+       T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
+
+       /*
+        * RData.
+        */
+       switch (type) {
+       case ns_t_a:
+               if (rdlen != (size_t)NS_INADDRSZ)
+                       goto formerr;
+               (void) inet_ntop(AF_INET, rdata, buf, buflen);
+               addlen(strlen(buf), &buf, &buflen);
+               break;
+
+       case ns_t_cname:
+       case ns_t_mb:
+       case ns_t_mg:
+       case ns_t_mr:
+       case ns_t_ns:
+       case ns_t_ptr:
+       case ns_t_dname:
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               break;
+
+       case ns_t_hinfo:
+       case ns_t_isdn:
+               /* First word. */
+               T(len = charstr(rdata, edata, &buf, &buflen));
+               if (len == 0)
+                       goto formerr;
+               rdata += len;
+               T(addstr(" ", 1, &buf, &buflen));
+
+                   
+               /* Second word, optional in ISDN records. */
+               if (type == ns_t_isdn && rdata == edata)
+                       break;
+                   
+               T(len = charstr(rdata, edata, &buf, &buflen));
+               if (len == 0)
+                       goto formerr;
+               rdata += len;
+               break;
+
+       case ns_t_soa: {
+               u_long t;
+
+               /* Server name. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               T(addstr(" ", 1, &buf, &buflen));
+
+               /* Administrator name. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               T(addstr(" (\n", 3, &buf, &buflen));
+               spaced = 0;
+
+               if ((edata - rdata) != 5*NS_INT32SZ)
+                       goto formerr;
+
+               /* Serial number. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+               len = SPRINTF((tmp, "%lu", t));
+               T(addstr(tmp, len, &buf, &buflen));
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+               T(addstr("; serial\n", 9, &buf, &buflen));
+               spaced = 0;
+
+               /* Refresh interval. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+               T(len = ns_format_ttl(t, buf, buflen));
+               addlen(len, &buf, &buflen);
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+               T(addstr("; refresh\n", 10, &buf, &buflen));
+               spaced = 0;
+
+               /* Retry interval. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+               T(len = ns_format_ttl(t, buf, buflen));
+               addlen(len, &buf, &buflen);
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+               T(addstr("; retry\n", 8, &buf, &buflen));
+               spaced = 0;
+
+               /* Expiry. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+               T(len = ns_format_ttl(t, buf, buflen));
+               addlen(len, &buf, &buflen);
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+               T(addstr("; expiry\n", 9, &buf, &buflen));
+               spaced = 0;
+
+               /* Minimum TTL. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
+               T(len = ns_format_ttl(t, buf, buflen));
+               addlen(len, &buf, &buflen);
+               T(addstr(" )", 2, &buf, &buflen));
+               T(spaced = addtab(len, 16, spaced, &buf, &buflen));
+               T(addstr("; minimum\n", 10, &buf, &buflen));
+
+               break;
+           }
+
+       case ns_t_mx:
+       case ns_t_afsdb:
+       case ns_t_rt: {
+               u_int t;
+
+               if (rdlen < (size_t)NS_INT16SZ)
+                       goto formerr;
+
+               /* Priority. */
+               t = ns_get16(rdata);
+               rdata += NS_INT16SZ;
+               len = SPRINTF((tmp, "%u ", t));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* Target. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+               break;
+           }
+
+       case ns_t_px: {
+               u_int t;
+
+               if (rdlen < (size_t)NS_INT16SZ)
+                       goto formerr;
+
+               /* Priority. */
+               t = ns_get16(rdata);
+               rdata += NS_INT16SZ;
+               len = SPRINTF((tmp, "%u ", t));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* Name1. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               T(addstr(" ", 1, &buf, &buflen));
+
+               /* Name2. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+               break;
+           }
+
+       case ns_t_x25:
+               T(len = charstr(rdata, edata, &buf, &buflen));
+               if (len == 0)
+                       goto formerr;
+               rdata += len;
+               break;
+
+       case ns_t_txt:
+               while (rdata < edata) {
+                       T(len = charstr(rdata, edata, &buf, &buflen));
+                       if (len == 0)
+                               goto formerr;
+                       rdata += len;
+                       if (rdata < edata)
+                               T(addstr(" ", 1, &buf, &buflen));
+               }
+               break;
+
+       case ns_t_nsap: {
+               char t[2+255*3];
+
+               (void) inet_nsap_ntoa(rdlen, rdata, t);
+               T(addstr(t, strlen(t), &buf, &buflen));
+               break;
+           }
+
+       case ns_t_aaaa:
+               if (rdlen != (size_t)NS_IN6ADDRSZ)
+                       goto formerr;
+               (void) inet_ntop(AF_INET6, rdata, buf, buflen);
+               addlen(strlen(buf), &buf, &buflen);
+               break;
+
+       case ns_t_loc: {
+               char t[255];
+
+               /* XXX protocol format checking? */
+               (void) loc_ntoa(rdata, t);
+               T(addstr(t, strlen(t), &buf, &buflen));
+               break;
+           }
+
+       case ns_t_naptr: {
+               u_int order, preference;
+               char t[50];
+
+               if (rdlen < 2U*NS_INT16SZ)
+                       goto formerr;
+
+               /* Order, Precedence. */
+               order = ns_get16(rdata);        rdata += NS_INT16SZ;
+               preference = ns_get16(rdata);   rdata += NS_INT16SZ;
+               len = SPRINTF((t, "%u %u ", order, preference));
+               T(addstr(t, len, &buf, &buflen));
+
+               /* Flags. */
+               T(len = charstr(rdata, edata, &buf, &buflen));
+               if (len == 0)
+                       goto formerr;
+               rdata += len;
+               T(addstr(" ", 1, &buf, &buflen));
+
+               /* Service. */
+               T(len = charstr(rdata, edata, &buf, &buflen));
+               if (len == 0)
+                       goto formerr;
+               rdata += len;
+               T(addstr(" ", 1, &buf, &buflen));
+
+               /* Regexp. */
+               T(len = charstr(rdata, edata, &buf, &buflen));
+               if (len < 0)
+                       return (-1);
+               if (len == 0)
+                       goto formerr;
+               rdata += len;
+               T(addstr(" ", 1, &buf, &buflen));
+
+               /* Server. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               break;
+           }
+
+       case ns_t_srv: {
+               u_int priority, weight, port;
+               char t[50];
+
+               if (rdlen < 3U*NS_INT16SZ)
+                       goto formerr;
+
+               /* Priority, Weight, Port. */
+               priority = ns_get16(rdata);  rdata += NS_INT16SZ;
+               weight   = ns_get16(rdata);  rdata += NS_INT16SZ;
+               port     = ns_get16(rdata);  rdata += NS_INT16SZ;
+               len = SPRINTF((t, "%u %u %u ", priority, weight, port));
+               T(addstr(t, len, &buf, &buflen));
+
+               /* Server. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               break;
+           }
+
+       case ns_t_minfo:
+       case ns_t_rp:
+               /* Name1. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               T(addstr(" ", 1, &buf, &buflen));
+
+               /* Name2. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+               break;
+
+       case ns_t_wks: {
+               int n, lcnt;
+
+               if (rdlen < 1U + NS_INT32SZ)
+                       goto formerr;
+
+               /* Address. */
+               (void) inet_ntop(AF_INET, rdata, buf, buflen);
+               addlen(strlen(buf), &buf, &buflen);
+               rdata += NS_INADDRSZ;
+
+               /* Protocol. */
+               len = SPRINTF((tmp, " %u ( ", *rdata));
+               T(addstr(tmp, len, &buf, &buflen));
+               rdata += NS_INT8SZ;
+
+               /* Bit map. */
+               n = 0;
+               lcnt = 0;
+               while (rdata < edata) {
+                       u_int c = *rdata++;
+                       do {
+                               if (c & 0200) {
+                                       if (lcnt == 0) {
+                                               T(addstr("\n\t\t\t\t", 5,
+                                                        &buf, &buflen));
+                                               lcnt = 10;
+                                               spaced = 0;
+                                       }
+                                       len = SPRINTF((tmp, "%d ", n));
+                                       T(addstr(tmp, len, &buf, &buflen));
+                                       lcnt--;
+                               }
+                               c <<= 1;
+                       } while (++n & 07);
+               }
+               T(addstr(")", 1, &buf, &buflen));
+
+               break;
+           }
+
+       case ns_t_key: {
+               char base64_key[NS_MD5RSA_MAX_BASE64];
+               u_int keyflags, protocol, algorithm, key_id;
+               const char *leader;
+               int n;
+
+               if (rdlen < 0U + NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
+                       goto formerr;
+
+               /* Key flags, Protocol, Algorithm. */
+#ifndef _LIBC
+               key_id = dst_s_dns_key_id(rdata, edata-rdata);
+#else
+               key_id = 0;
+#endif
+               keyflags = ns_get16(rdata);  rdata += NS_INT16SZ;
+               protocol = *rdata++;
+               algorithm = *rdata++;
+               len = SPRINTF((tmp, "0x%04x %u %u",
+                              keyflags, protocol, algorithm));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* Public key data. */
+               len = b64_ntop(rdata, edata - rdata,
+                              base64_key, sizeof base64_key);
+               if (len < 0)
+                       goto formerr;
+               if (len > 15) {
+                       T(addstr(" (", 2, &buf, &buflen));
+                       leader = "\n\t\t";
+                       spaced = 0;
+               } else
+                       leader = " ";
+               for (n = 0; n < len; n += 48) {
+                       T(addstr(leader, strlen(leader), &buf, &buflen));
+                       T(addstr(base64_key + n, MIN(len - n, 48),
+                                &buf, &buflen));
+               }
+               if (len > 15)
+                       T(addstr(" )", 2, &buf, &buflen));
+               n = SPRINTF((tmp, " ; key_tag= %u", key_id));
+               T(addstr(tmp, n, &buf, &buflen));
+
+               break;
+           }
+
+       case ns_t_sig: {
+               char base64_key[NS_MD5RSA_MAX_BASE64];
+               u_int type, algorithm, labels, footprint;
+               const char *leader;
+               u_long t;
+               int n;
+
+               if (rdlen < 22U)
+                       goto formerr;
+
+               /* Type covered, Algorithm, Label count, Original TTL. */
+               type = ns_get16(rdata);  rdata += NS_INT16SZ;
+               algorithm = *rdata++;
+               labels = *rdata++;
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               len = SPRINTF((tmp, "%s %d %d %lu ",
+                              p_type(type), algorithm, labels, t));
+               T(addstr(tmp, len, &buf, &buflen));
+               if (labels > (u_int)dn_count_labels(name))
+                       goto formerr;
+
+               /* Signature expiry. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* Time signed. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* Signature Footprint. */
+               footprint = ns_get16(rdata);  rdata += NS_INT16SZ;
+               len = SPRINTF((tmp, "%u ", footprint));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* Signer's name. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+               /* Signature. */
+               len = b64_ntop(rdata, edata - rdata,
+                              base64_key, sizeof base64_key);
+               if (len > 15) {
+                       T(addstr(" (", 2, &buf, &buflen));
+                       leader = "\n\t\t";
+                       spaced = 0;
+               } else
+                       leader = " ";
+               if (len < 0)
+                       goto formerr;
+               for (n = 0; n < len; n += 48) {
+                       T(addstr(leader, strlen(leader), &buf, &buflen));
+                       T(addstr(base64_key + n, MIN(len - n, 48),
+                                &buf, &buflen));
+               }
+               if (len > 15)
+                       T(addstr(" )", 2, &buf, &buflen));
+               break;
+           }
+
+       case ns_t_nxt: {
+               int n, c;
+
+               /* Next domain name. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+
+               /* Type bit map. */
+               n = edata - rdata;
+               for (c = 0; c < n*8; c++)
+                       if (NS_NXT_BIT_ISSET(c, rdata)) {
+                               len = SPRINTF((tmp, " %s", p_type(c)));
+                               T(addstr(tmp, len, &buf, &buflen));
+                       }
+               break;
+           }
+
+       case ns_t_cert: {
+               u_int c_type, key_tag, alg;
+               int n;
+               unsigned int siz;
+               char base64_cert[8192], tmp[40];
+               const char *leader;
+
+               c_type  = ns_get16(rdata); rdata += NS_INT16SZ;
+               key_tag = ns_get16(rdata); rdata += NS_INT16SZ;
+               alg = (u_int) *rdata++;
+
+               len = SPRINTF((tmp, "%d %d %d ", c_type, key_tag, alg));
+               T(addstr(tmp, len, &buf, &buflen));
+               siz = (edata-rdata)*4/3 + 4; /* "+4" accounts for trailing \0 */
+               if (siz > sizeof(base64_cert) * 3/4) {
+                       const char *str = "record too long to print";
+                       T(addstr(str, strlen(str), &buf, &buflen));
+               }
+               else {
+                       len = b64_ntop(rdata, edata-rdata, base64_cert, siz);
+
+                       if (len < 0)
+                               goto formerr;
+                       else if (len > 15) {
+                               T(addstr(" (", 2, &buf, &buflen));
+                               leader = "\n\t\t";
+                               spaced = 0;
+                       }
+                       else
+                               leader = " ";
+       
+                       for (n = 0; n < len; n += 48) {
+                               T(addstr(leader, strlen(leader),
+                                        &buf, &buflen));
+                               T(addstr(base64_cert + n, MIN(len - n, 48),
+                                        &buf, &buflen));
+                       }
+                       if (len > 15)
+                               T(addstr(" )", 2, &buf, &buflen));
+               }
+               break;
+           }
+
+       case ns_t_tkey: {
+               /* KJD - need to complete this */
+               u_long t;
+               int mode, err, keysize;
+
+               /* Algorithm name. */
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               T(addstr(" ", 1, &buf, &buflen));
+
+               /* Inception. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* Experation. */
+               t = ns_get32(rdata);  rdata += NS_INT32SZ;
+               len = SPRINTF((tmp, "%s ", p_secstodate(t)));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* Mode , Error, Key Size. */
+               /* Priority, Weight, Port. */
+               mode = ns_get16(rdata);  rdata += NS_INT16SZ;
+               err  = ns_get16(rdata);  rdata += NS_INT16SZ;
+               keysize  = ns_get16(rdata);  rdata += NS_INT16SZ;
+               len = SPRINTF((tmp, "%u %u %u ", mode, err, keysize));
+               T(addstr(tmp, len, &buf, &buflen));
+
+               /* XXX need to dump key, print otherdata length & other data */
+               break;
+           }
+
+       case ns_t_tsig: {
+               /* BEW - need to complete this */
+               int n;
+
+               T(len = addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               T(addstr(" ", 1, &buf, &buflen));
+               rdata += 8; /*%< time */
+               n = ns_get16(rdata); rdata += INT16SZ;
+               rdata += n; /*%< sig */
+               n = ns_get16(rdata); rdata += INT16SZ; /*%< original id */
+               sprintf(buf, "%d", ns_get16(rdata));
+               rdata += INT16SZ;
+               addlen(strlen(buf), &buf, &buflen);
+               break;
+           }
+
+       case ns_t_a6: {
+               struct in6_addr a;
+               int pbyte, pbit;
+
+               /* prefix length */
+               if (rdlen == 0U) goto formerr;
+               len = SPRINTF((tmp, "%d ", *rdata));
+               T(addstr(tmp, len, &buf, &buflen));
+               pbit = *rdata;
+               if (pbit > 128) goto formerr;
+               pbyte = (pbit & ~7) / 8;
+               rdata++;
+
+               /* address suffix: provided only when prefix len != 128 */
+               if (pbit < 128) {
+                       if (rdata + pbyte >= edata) goto formerr;
+                       memset(&a, 0, sizeof(a));
+                       memcpy(&a.s6_addr[pbyte], rdata, sizeof(a) - pbyte);
+                       (void) inet_ntop(AF_INET6, &a, buf, buflen);
+                       addlen(strlen(buf), &buf, &buflen);
+                       rdata += sizeof(a) - pbyte;
+               }
+
+               /* prefix name: provided only when prefix len > 0 */
+               if (pbit == 0)
+                       break;
+               if (rdata >= edata) goto formerr;
+               T(addstr(" ", 1, &buf, &buflen));
+               T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
+               
+               break;
+           }
+
+       case ns_t_opt: {
+               len = SPRINTF((tmp, "%u bytes", class));
+               T(addstr(tmp, len, &buf, &buflen));
+               break;
+           }
+
+       default:
+               comment = "unknown RR type";
+               goto hexify;
+       }
+       return (buf - obuf);
+ formerr:
+       comment = "RR format error";
+ hexify: {
+       int n, m;
+       char *p;
+
+       len = SPRINTF((tmp, "\\# %u%s\t; %s", (unsigned)(edata - rdata),
+                      rdlen != 0U ? " (" : "", comment));
+       T(addstr(tmp, len, &buf, &buflen));
+       while (rdata < edata) {
+               p = tmp;
+               p += SPRINTF((p, "\n\t"));
+               spaced = 0;
+               n = MIN(16, edata - rdata);
+               for (m = 0; m < n; m++)
+                       p += SPRINTF((p, "%02x ", rdata[m]));
+               T(addstr(tmp, p - tmp, &buf, &buflen));
+               if (n < 16) {
+                       T(addstr(")", 1, &buf, &buflen));
+                       T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
+               }
+               p = tmp;
+               p += SPRINTF((p, "; "));
+               for (m = 0; m < n; m++)
+                       *p++ = (isascii(rdata[m]) && isprint(rdata[m]))
+                               ? rdata[m]
+                               : '.';
+               T(addstr(tmp, p - tmp, &buf, &buflen));
+               rdata += n;
+       }
+       return (buf - obuf);
+    }
+}
+
+/* Private. */
+
+/*%
+ * size_t
+ * prune_origin(name, origin)
+ *     Find out if the name is at or under the current origin.
+ * return:
+ *     Number of characters in name before start of origin,
+ *     or length of name if origin does not match.
+ * notes:
+ *     This function should share code with samedomain().
+ */
+static size_t
+prune_origin(const char *name, const char *origin) {
+       const char *oname = name;
+
+       while (*name != '\0') {
+               if (origin != NULL && ns_samename(name, origin) == 1)
+                       return (name - oname - (name > oname));
+               while (*name != '\0') {
+                       if (*name == '\\') {
+                               name++;
+                               /* XXX need to handle \nnn form. */
+                               if (*name == '\0')
+                                       break;
+                       } else if (*name == '.') {
+                               name++;
+                               break;
+                       }
+                       name++;
+               }
+       }
+       return (name - oname);
+}
+
+/*%
+ * int
+ * charstr(rdata, edata, buf, buflen)
+ *     Format a <character-string> into the presentation buffer.
+ * return:
+ *     Number of rdata octets consumed
+ *     0 for protocol format error
+ *     -1 for output buffer error
+ * side effects:
+ *     buffer is advanced on success.
+ */
+static int
+charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
+       const u_char *odata = rdata;
+       size_t save_buflen = *buflen;
+       char *save_buf = *buf;
+
+       if (addstr("\"", 1, buf, buflen) < 0)
+               goto enospc;
+       if (rdata < edata) {
+               int n = *rdata;
+
+               if (rdata + 1 + n <= edata) {
+                       rdata++;
+                       while (n-- > 0) {
+                               if (strchr("\n\"\\", *rdata) != NULL)
+                                       if (addstr("\\", 1, buf, buflen) < 0)
+                                               goto enospc;
+                               if (addstr((const char *)rdata, 1,
+                                          buf, buflen) < 0)
+                                       goto enospc;
+                               rdata++;
+                       }
+               }
+       }
+       if (addstr("\"", 1, buf, buflen) < 0)
+               goto enospc;
+       return (rdata - odata);
+ enospc:
+       errno = ENOSPC;
+       *buf = save_buf;
+       *buflen = save_buflen;
+       return (-1);
+}
+
+static int
+addname(const u_char *msg, size_t msglen,
+       const u_char **pp, const char *origin,
+       char **buf, size_t *buflen)
+{
+       size_t newlen, save_buflen = *buflen;
+       char *save_buf = *buf;
+       int n;
+
+       n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
+       if (n < 0)
+               goto enospc;    /*%< Guess. */
+       newlen = prune_origin(*buf, origin);
+       if (**buf == '\0') {
+               goto root;
+       } else if (newlen == 0U) {
+               /* Use "@" instead of name. */
+               if (newlen + 2 > *buflen)
+                       goto enospc;        /* No room for "@\0". */
+               (*buf)[newlen++] = '@';
+               (*buf)[newlen] = '\0';
+       } else {
+               if (((origin == NULL || origin[0] == '\0') ||
+                   (origin[0] != '.' && origin[1] != '\0' &&
+                   (*buf)[newlen] == '\0')) && (*buf)[newlen - 1] != '.') {
+                       /* No trailing dot. */
+ root:
+                       if (newlen + 2 > *buflen)
+                               goto enospc;    /* No room for ".\0". */
+                       (*buf)[newlen++] = '.';
+                       (*buf)[newlen] = '\0';
+               }
+       }
+       *pp += n;
+       addlen(newlen, buf, buflen);
+       **buf = '\0';
+       return (newlen);
+ enospc:
+       errno = ENOSPC;
+       *buf = save_buf;
+       *buflen = save_buflen;
+       return (-1);
+}
+
+static void
+addlen(size_t len, char **buf, size_t *buflen) {
+       INSIST(len <= *buflen);
+       *buf += len;
+       *buflen -= len;
+}
+
+static int
+addstr(const char *src, size_t len, char **buf, size_t *buflen) {
+       if (len >= *buflen) {
+               errno = ENOSPC;
+               return (-1);
+       }
+       memcpy(*buf, src, len);
+       addlen(len, buf, buflen);
+       **buf = '\0';
+       return (0);
+}
+
+static int
+addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
+       size_t save_buflen = *buflen;
+       char *save_buf = *buf;
+       int t;
+
+       if (spaced || len >= target - 1) {
+               T(addstr("  ", 2, buf, buflen));
+               spaced = 1;
+       } else {
+               for (t = (target - len - 1) / 8; t >= 0; t--)
+                       if (addstr("\t", 1, buf, buflen) < 0) {
+                               *buflen = save_buflen;
+                               *buf = save_buf;
+                               return (-1);
+                       }
+               spaced = 0;
+       }
+       return (spaced);
+}
+
+/*! \file */
diff --git a/lib/libc/nameser/ns_samedomain.c b/lib/libc/nameser/ns_samedomain.c
new file mode 100644 (file)
index 0000000..ee89009
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995,1999 by 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 lint
+static const char rcsid[] = "$Id: ns_samedomain.c,v 1.6 2005/04/27 04:56:40 sra Exp $";
+#endif
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <arpa/nameser.h>
+#include <errno.h>
+#include <string.h>
+
+#include "port_after.h"
+
+/*%
+ *     Check whether a name belongs to a domain.
+ *
+ * Inputs:
+ *\li  a - the domain whose ancestory is being verified
+ *\li  b - the potential ancestor we're checking against
+ *
+ * Return:
+ *\li  boolean - is a at or below b?
+ *
+ * Notes:
+ *\li  Trailing dots are first removed from name and domain.
+ *     Always compare complete subdomains, not only whether the
+ *     domain name is the trailing string of the given name.
+ *
+ *\li  "host.foobar.top" lies in "foobar.top" and in "top" and in ""
+ *     but NOT in "bar.top"
+ */
+
+int
+ns_samedomain(const char *a, const char *b) {
+       size_t la, lb;
+       int diff, i, escaped;
+       const char *cp;
+
+       la = strlen(a);
+       lb = strlen(b);
+
+       /* Ignore a trailing label separator (i.e. an unescaped dot) in 'a'. */
+       if (la != 0U && a[la - 1] == '.') {
+               escaped = 0;
+               /* Note this loop doesn't get executed if la==1. */
+               for (i = la - 2; i >= 0; i--)
+                       if (a[i] == '\\') {
+                               if (escaped)
+                                       escaped = 0;
+                               else
+                                       escaped = 1;
+                       } else
+                               break;
+               if (!escaped)
+                       la--;
+       }
+
+       /* Ignore a trailing label separator (i.e. an unescaped dot) in 'b'. */
+       if (lb != 0U && b[lb - 1] == '.') {
+               escaped = 0;
+               /* note this loop doesn't get executed if lb==1 */
+               for (i = lb - 2; i >= 0; i--)
+                       if (b[i] == '\\') {
+                               if (escaped)
+                                       escaped = 0;
+                               else
+                                       escaped = 1;
+                       } else
+                               break;
+               if (!escaped)
+                       lb--;
+       }
+
+       /* lb == 0 means 'b' is the root domain, so 'a' must be in 'b'. */
+       if (lb == 0U)
+               return (1);
+
+       /* 'b' longer than 'a' means 'a' can't be in 'b'. */
+       if (lb > la)
+               return (0);
+
+       /* 'a' and 'b' being equal at this point indicates sameness. */
+       if (lb == la)
+               return (strncasecmp(a, b, lb) == 0);
+
+       /* Ok, we know la > lb. */
+
+       diff = la - lb;
+
+       /*
+        * If 'a' is only 1 character longer than 'b', then it can't be
+        * a subdomain of 'b' (because of the need for the '.' label
+        * separator).
+        */
+       if (diff < 2)
+               return (0);
+
+       /*
+        * If the character before the last 'lb' characters of 'b'
+        * isn't '.', then it can't be a match (this lets us avoid
+        * having "foobar.com" match "bar.com").
+        */
+       if (a[diff - 1] != '.')
+               return (0);
+
+       /*
+        * We're not sure about that '.', however.  It could be escaped
+         * and thus not a really a label separator.
+        */
+       escaped = 0;
+       for (i = diff - 2; i >= 0; i--)
+               if (a[i] == '\\') {
+                       if (escaped)
+                               escaped = 0;
+                       else
+                               escaped = 1;
+               } else
+                       break;
+       if (escaped)
+               return (0);
+         
+       /* Now compare aligned trailing substring. */
+       cp = a + diff;
+       return (strncasecmp(cp, b, lb) == 0);
+}
+
+#ifndef _LIBC
+/*
+ * int
+ * ns_subdomain(a, b)
+ *     is "a" a subdomain of "b"?
+ */
+int
+ns_subdomain(const char *a, const char *b) {
+       return (ns_samename(a, b) != 1 && ns_samedomain(a, b));
+}
+#endif
+
+/*%
+ *     make a canonical copy of domain name "src"
+ *
+ * notes:
+ * \code
+ *     foo -> foo.
+ *     foo. -> foo.
+ *     foo.. -> foo.
+ *     foo\. -> foo\..
+ *     foo\\. -> foo\\.
+ * \endcode
+ */
+
+int
+ns_makecanon(const char *src, char *dst, size_t dstsize) {
+       size_t n = strlen(src);
+
+       if (n + sizeof "." > dstsize) {                 /*%< Note: sizeof == 2 */
+               errno = EMSGSIZE;
+               return (-1);
+       }
+       strcpy(dst, src);
+       while (n >= 1U && dst[n - 1] == '.')            /*%< Ends in "." */
+               if (n >= 2U && dst[n - 2] == '\\' &&    /*%< Ends in "\." */
+                   (n < 3U || dst[n - 3] != '\\'))     /*%< But not "\\." */
+                       break;
+               else
+                       dst[--n] = '\0';
+       dst[n++] = '.';
+       dst[n] = '\0';
+       return (0);
+}
+
+/*%
+ *     determine whether domain name "a" is the same as domain name "b"
+ *
+ * return:
+ *\li  -1 on error
+ *\li  0 if names differ
+ *\li  1 if names are the same
+ */
+
+int
+ns_samename(const char *a, const char *b) {
+       char ta[NS_MAXDNAME], tb[NS_MAXDNAME];
+
+       if (ns_makecanon(a, ta, sizeof ta) < 0 ||
+           ns_makecanon(b, tb, sizeof tb) < 0)
+               return (-1);
+       if (strcasecmp(ta, tb) == 0)
+               return (1);
+       else
+               return (0);
+}
+
+/*! \file */
diff --git a/lib/libc/nameser/ns_ttl.c b/lib/libc/nameser/ns_ttl.c
new file mode 100644 (file)
index 0000000..69c2f83
--- /dev/null
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1996,1999 by 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 lint
+static const char rcsid[] = "$Id: ns_ttl.c,v 1.4 2005/07/28 06:51:49 marka Exp $";
+#endif
+
+/* Import. */
+
+#include "port_before.h"
+
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "port_after.h"
+
+#ifdef SPRINTF_CHAR
+# define SPRINTF(x) strlen(sprintf/**/x)
+#else
+# define SPRINTF(x) ((size_t)sprintf x)
+#endif
+
+/* Forward. */
+
+static int     fmt1(int t, char s, char **buf, size_t *buflen);
+
+/* Macros. */
+
+#define T(x) if ((x) < 0) return (-1); else (void)NULL
+
+/* Public. */
+
+int
+ns_format_ttl(u_long src, char *dst, size_t dstlen) {
+       char *odst = dst;
+       int secs, mins, hours, days, weeks, x;
+       char *p;
+
+       secs = src % 60;   src /= 60;
+       mins = src % 60;   src /= 60;
+       hours = src % 24;  src /= 24;
+       days = src % 7;    src /= 7;
+       weeks = src;       src = 0;
+
+       x = 0;
+       if (weeks) {
+               T(fmt1(weeks, 'W', &dst, &dstlen));
+               x++;
+       }
+       if (days) {
+               T(fmt1(days, 'D', &dst, &dstlen));
+               x++;
+       }
+       if (hours) {
+               T(fmt1(hours, 'H', &dst, &dstlen));
+               x++;
+       }
+       if (mins) {
+               T(fmt1(mins, 'M', &dst, &dstlen));
+               x++;
+       }
+       if (secs || !(weeks || days || hours || mins)) {
+               T(fmt1(secs, 'S', &dst, &dstlen));
+               x++;
+       }
+
+       if (x > 1) {
+               int ch;
+
+               for (p = odst; (ch = *p) != '\0'; p++)
+                       if (isascii(ch) && isupper(ch))
+                               *p = tolower(ch);
+       }
+
+       return (dst - odst);
+}
+
+int
+ns_parse_ttl(const char *src, u_long *dst) {
+       u_long ttl, tmp;
+       int ch, digits, dirty;
+
+       ttl = 0;
+       tmp = 0;
+       digits = 0;
+       dirty = 0;
+       while ((ch = *src++) != '\0') {
+               if (!isascii(ch) || !isprint(ch))
+                       goto einval;
+               if (isdigit(ch)) {
+                       tmp *= 10;
+                       tmp += (ch - '0');
+                       digits++;
+                       continue;
+               }
+               if (digits == 0)
+                       goto einval;
+               if (islower(ch))
+                       ch = toupper(ch);
+               switch (ch) {
+               case 'W':  tmp *= 7;
+               case 'D':  tmp *= 24;
+               case 'H':  tmp *= 60;
+               case 'M':  tmp *= 60;
+               case 'S':  break;
+               default:   goto einval;
+               }
+               ttl += tmp;
+               tmp = 0;
+               digits = 0;
+               dirty = 1;
+       }
+       if (digits > 0) {
+               if (dirty)
+                       goto einval;
+               else
+                       ttl += tmp;
+       } else if (!dirty)
+               goto einval;
+       *dst = ttl;
+       return (0);
+
+ einval:
+       errno = EINVAL;
+       return (-1);
+}
+
+/* Private. */
+
+static int
+fmt1(int t, char s, char **buf, size_t *buflen) {
+       char tmp[50];
+       size_t len;
+
+       len = SPRINTF((tmp, "%d%c", t, s));
+       if (len + 1 > *buflen)
+               return (-1);
+       strcpy(*buf, tmp);
+       *buf += len;
+       *buflen -= len;
+       return (0);
+}
+
+/*! \file */
index e7a6b05..9145e6c 100644 (file)
@@ -15,15 +15,14 @@ SRCS+=      base64.c ether_addr.c eui64.c \
        if_indextoname.c if_nameindex.c if_nametoindex.c \
        ip6opt.c linkaddr.c map_v4v6.c name6.c \
        nsdispatch.c nslexer.c nsparser.y nss_compat.c ntoh.c \
-       rcmd.c rcmdsh.c recv.c res_comp.c res_data.c res_debug.c \
-       res_init.c res_mkquery.c res_query.c res_send.c \
+       rcmd.c rcmdsh.c recv.c \
        rthdr.c sockatmark.c send.c vars.c
 
 .if !defined(NO_NS_CACHING)
 SRCS+= nscache.c nscachedcli.c
 .endif
 
-CFLAGS+=-DINET6 -I${.OBJDIR}
+CFLAGS+=-DINET6 -I${.OBJDIR} -I${.CURDIR}/resolv
 
 YFLAGS+=-p_nsyy
 LFLAGS+=-P_nsyy
index 8dc53ea..667431b 100644 (file)
@@ -1,21 +1,17 @@
-BINDDIR= ${.CURDIR}/../../contrib/bind/lib/bind
-
-.PATH: ${BINDDIR}/inet
+.PATH: ${.CURDIR}/inet
 SRCS+= inet_addr.c inet_cidr_ntop.c inet_cidr_pton.c inet_lnaof.c \
        inet_makeaddr.c inet_net_ntop.c inet_net_pton.c inet_neta.c \
        inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \
        inet_pton.c nsap_addr.c
 
-.PATH: ${BINDDIR}/isc
+.PATH: ${.CURDIR}/isc
 SRCS+= ev_streams.c ev_timers.c
 
-.PATH: ${BINDDIR}/nameser
+.PATH: ${.CURDIR}/nameser
 SRCS+= ns_name.c ns_netint.c ns_parse.c ns_print.c ns_samedomain.c ns_ttl.c
 
-.PATH: ${BINDDIR}/resolv ${.CURDIR}/../libc/resolv
+.PATH: ${.CURDIR}/resolv
 SRCS+= h_errno.c herror.c mtctxres.c res_comp.c res_data.c res_debug.c \
        res_findzonecut.c res_init.c res_mkquery.c res_mkupdate.c \
        res_query.c res_send.c res_state.c res_update.c
 
-MKDEP= -iquote ${BINDDIR}/include -idirafter ${BINDDIR}/resolv
-CFLAGS+= ${MKDEP}
diff --git a/lib/libc/resolv/herror.c b/lib/libc/resolv/herror.c
new file mode 100644 (file)
index 0000000..a342237
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1987, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)herror.c     8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$Id: herror.c,v 1.4 2005/04/27 04:56:41 sra Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#ifdef _LIBC
+#include "namespace.h"
+#endif
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/uio.h>
+
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <netdb.h>
+#include <resolv.h>
+#include <string.h>
+#include <unistd.h>
+#ifndef _LIBC
+#include <irs.h>
+#else
+#include "un-namespace.h"
+#endif
+
+#include "port_after.h"
+
+const char *h_errlist[] = {
+       "Resolver Error 0 (no error)",
+       "Unknown host",                         /*%< 1 HOST_NOT_FOUND */
+       "Host name lookup failure",             /*%< 2 TRY_AGAIN */
+       "Unknown server error",                 /*%< 3 NO_RECOVERY */
+       "No address associated with name",      /*%< 4 NO_ADDRESS */
+};
+int    h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
+
+#if !(__GLIBC__ > 2 || __GLIBC__ == 2 &&  __GLIBC_MINOR__ >= 3)
+#undef h_errno
+int    h_errno;
+#endif
+
+/*%
+ * herror --
+ *     print the error indicated by the h_errno value.
+ */
+void
+herror(const char *s) {
+       struct iovec iov[4], *v = iov;
+       char *t;
+
+       if (s != NULL && *s != '\0') {
+               DE_CONST(s, t);
+               v->iov_base = t;
+               v->iov_len = strlen(t);
+               v++;
+               DE_CONST(": ", t);
+               v->iov_base = t;
+               v->iov_len = 2;
+               v++;
+       }
+       DE_CONST(hstrerror(*__h_errno()), t);
+       v->iov_base = t;
+       v->iov_len = strlen(v->iov_base);
+       v++;
+       DE_CONST("\n", t);
+       v->iov_base = t;
+       v->iov_len = 1;
+#ifndef _LIBC
+       writev(STDERR_FILENO, iov, (v - iov) + 1);
+#else
+       _writev(STDERR_FILENO, iov, (v - iov) + 1);
+#endif
+}
+
+/*%
+ * hstrerror --
+ *     return the string associated with a given "host" errno value.
+ */
+const char *
+hstrerror(int err) {
+       if (err < 0)
+               return ("Resolver internal error");
+       else if (err < h_nerr)
+               return (h_errlist[err]);
+       return ("Unknown resolver error");
+}
+
+/*! \file */
diff --git a/lib/libc/resolv/mtctxres.c b/lib/libc/resolv/mtctxres.c
new file mode 100644 (file)
index 0000000..6f9f586
--- /dev/null
@@ -0,0 +1,142 @@
+#include <port_before.h>
+#ifdef DO_PTHREADS
+#include <pthread.h>
+#ifdef _LIBC
+#include <pthread_np.h>
+#endif
+#endif
+#include <errno.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <string.h>
+#include "resolv_mt.h"
+#ifndef _LIBC
+#include <irs.h>
+#endif
+#include <port_after.h>
+
+#ifdef DO_PTHREADS
+static pthread_key_t   key;
+static int             mt_key_initialized = 0;
+
+static int             __res_init_ctx(void);
+static void            __res_destroy_ctx(void *);
+
+#if defined(sun) && !defined(__GNUC__)
+#pragma init   (_mtctxres_init)
+#endif
+#endif
+
+static mtctxres_t      sharedctx;
+
+#ifdef DO_PTHREADS
+/*
+ * Initialize the TSD key. By doing this at library load time, we're
+ * implicitly running without interference from other threads, so there's
+ * no need for locking.
+ */
+static void
+_mtctxres_init(void) {
+       int pthread_keycreate_ret;
+
+       pthread_keycreate_ret = pthread_key_create(&key, __res_destroy_ctx);
+       if (pthread_keycreate_ret == 0)
+               mt_key_initialized = 1;
+}
+#endif
+
+#ifndef _LIBC
+/*
+ * To support binaries that used the private MT-safe interface in
+ * Solaris 8, we still need to provide the __res_enable_mt()
+ * and __res_disable_mt() entry points. They're do-nothing routines.
+ */
+int
+__res_enable_mt(void) {
+       return (-1);
+}
+#endif
+
+int
+__res_disable_mt(void) {
+       return (0);
+}
+
+#ifdef DO_PTHREADS
+static int
+__res_init_ctx(void) {
+
+       mtctxres_t      *mt;
+       int             ret;
+
+
+       if (pthread_getspecific(key) != 0) {
+               /* Already exists */
+               return (0);
+       }
+
+       if ((mt = malloc(sizeof (mtctxres_t))) == 0) {
+               errno = ENOMEM;
+               return (-1);
+       }
+
+       memset(mt, 0, sizeof (mtctxres_t));
+
+       if ((ret = pthread_setspecific(key, mt)) != 0) {
+               free(mt);
+               errno = ret;
+               return (-1);
+       }
+
+       return (0);
+}
+
+static void
+__res_destroy_ctx(void *value) {
+
+       mtctxres_t      *mt = (mtctxres_t *)value;
+
+       if (mt != 0)
+               free(mt);
+}
+#endif
+
+mtctxres_t *
+___mtctxres(void) {
+#ifdef DO_PTHREADS
+       mtctxres_t      *mt;
+
+#ifdef _LIBC
+       if (pthread_main_np() != 0)
+               return (&sharedctx);
+#endif
+
+
+       /*
+        * This if clause should only be executed if we are linking
+        * statically.  When linked dynamically _mtctxres_init() should
+        * be called at binding time due the #pragma above.
+        */
+       if (!mt_key_initialized) {
+               static pthread_mutex_t keylock = PTHREAD_MUTEX_INITIALIZER;
+                if (pthread_mutex_lock(&keylock) == 0) {
+                       _mtctxres_init();
+                       (void) pthread_mutex_unlock(&keylock);
+               }
+       }
+
+       /*
+        * If we have already been called in this thread return the existing
+        * context.  Otherwise recreat a new context and return it.  If
+        * that fails return a global context.
+        */
+       if (mt_key_initialized) {
+               if (((mt = pthread_getspecific(key)) != 0) ||
+                   (__res_init_ctx() == 0 &&
+                    (mt = pthread_getspecific(key)) != 0)) {
+                       return (mt);
+               }
+       }
+#endif
+       return (&sharedctx);
+}
diff --git a/lib/libc/resolv/res_comp.c b/lib/libc/resolv/res_comp.c
new file mode 100644 (file)
index 0000000..af182ee
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 1985, 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.
+ */
+
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Portions Copyright (c) 1996-1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char sccsid[] = "@(#)res_comp.c   8.1 (Berkeley) 6/4/93";
+static const char rcsid[] = "$Id: res_comp.c,v 1.5 2005/07/28 06:51:50 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+#include <sys/types.h>
+#include <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <ctype.h>
+#include <resolv.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include "port_after.h"
+
+/*%
+ * Expand compressed domain name 'src' to full domain name.
+ *
+ * \li 'msg' is a pointer to the begining of the message,
+ * \li 'eom' points to the first location after the message,
+ * \li 'dst' is a pointer to a buffer of size 'dstsiz' for the result.
+ * \li Return size of compressed name or -1 if there was an error.
+ */
+int
+dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
+         char *dst, int dstsiz)
+{
+       int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
+
+       if (n > 0 && dst[0] == '.')
+               dst[0] = '\0';
+       return (n);
+}
+
+/*%
+ * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
+ *
+ * \li Return the size of the compressed name or -1.
+ * \li 'length' is the size of the array pointed to by 'comp_dn'.
+ */
+int
+dn_comp(const char *src, u_char *dst, int dstsiz,
+       u_char **dnptrs, u_char **lastdnptr)
+{
+       return (ns_name_compress(src, dst, (size_t)dstsiz,
+                                (const u_char **)dnptrs,
+                                (const u_char **)lastdnptr));
+}
+
+/*%
+ * Skip over a compressed domain name. Return the size or -1.
+ */
+int
+dn_skipname(const u_char *ptr, const u_char *eom) {
+       const u_char *saveptr = ptr;
+
+       if (ns_name_skip(&ptr, eom) == -1)
+               return (-1);
+       return (ptr - saveptr);
+}
+
+/*%
+ * Verify that a domain name uses an acceptable character set.
+ *
+ * Note the conspicuous absence of ctype macros in these definitions.  On
+ * non-ASCII hosts, we can't depend on string literals or ctype macros to
+ * tell us anything about network-format data.  The rest of the BIND system
+ * is not careful about this, but for some reason, we're doing it right here.
+ */
+#define PERIOD 0x2e
+#define        hyphenchar(c) ((c) == 0x2d)
+#define bslashchar(c) ((c) == 0x5c)
+#define periodchar(c) ((c) == PERIOD)
+#define asterchar(c) ((c) == 0x2a)
+#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
+                  || ((c) >= 0x61 && (c) <= 0x7a))
+#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
+
+#define borderchar(c) (alphachar(c) || digitchar(c))
+#define middlechar(c) (borderchar(c) || hyphenchar(c))
+#define        domainchar(c) ((c) > 0x20 && (c) < 0x7f)
+
+int
+res_hnok(const char *dn) {
+       int pch = PERIOD, ch = *dn++;
+
+       while (ch != '\0') {
+               int nch = *dn++;
+
+               if (periodchar(ch)) {
+                       (void)NULL;
+               } else if (periodchar(pch)) {
+                       if (!borderchar(ch))
+                               return (0);
+               } else if (periodchar(nch) || nch == '\0') {
+                       if (!borderchar(ch))
+                               return (0);
+               } else {
+                       if (!middlechar(ch))
+                               return (0);
+               }
+               pch = ch, ch = nch;
+       }
+       return (1);
+}
+
+/*%
+ * hostname-like (A, MX, WKS) owners can have "*" as their first label
+ * but must otherwise be as a host name.
+ */
+int
+res_ownok(const char *dn) {
+       if (asterchar(dn[0])) {
+               if (periodchar(dn[1]))
+                       return (res_hnok(dn+2));
+               if (dn[1] == '\0')
+                       return (1);
+       }
+       return (res_hnok(dn));
+}
+
+/*%
+ * SOA RNAMEs and RP RNAMEs can have any printable character in their first
+ * label, but the rest of the name has to look like a host name.
+ */
+int
+res_mailok(const char *dn) {
+       int ch, escaped = 0;
+
+       /* "." is a valid missing representation */
+       if (*dn == '\0')
+               return (1);
+
+       /* otherwise <label>.<hostname> */
+       while ((ch = *dn++) != '\0') {
+               if (!domainchar(ch))
+                       return (0);
+               if (!escaped && periodchar(ch))
+                       break;
+               if (escaped)
+                       escaped = 0;
+               else if (bslashchar(ch))
+                       escaped = 1;
+       }
+       if (periodchar(ch))
+               return (res_hnok(dn));
+       return (0);
+}
+
+/*%
+ * This function is quite liberal, since RFC1034's character sets are only
+ * recommendations.
+ */
+int
+res_dnok(const char *dn) {
+       int ch;
+
+       while ((ch = *dn++) != '\0')
+               if (!domainchar(ch))
+                       return (0);
+       return (1);
+}
+
+#ifdef BIND_4_COMPAT
+/*%
+ * This module must export the following externally-visible symbols:
+ *     ___putlong
+ *     ___putshort
+ *     __getlong
+ *     __getshort
+ * Note that one _ comes from C and the others come from us.
+ */
+
+#ifdef SOLARIS2
+#ifdef  __putlong
+#undef  __putlong
+#endif
+#ifdef  __putshort
+#undef  __putshort
+#endif
+#pragma weak    putlong         =       __putlong
+#pragma weak    putshort        =       __putshort
+#endif /* SOLARIS2 */
+
+void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
+void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
+#ifndef __ultrix__
+u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
+u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
+#endif /*__ultrix__*/
+#endif /*BIND_4_COMPAT*/
+
+#ifdef _LIBC
+/*
+ * Weak aliases for applications that use certain private entry points,
+ * and fail to include <resolv.h>.
+ */
+#undef dn_comp
+__weak_reference(__dn_comp, dn_comp);
+#undef dn_expand
+__weak_reference(__dn_expand, dn_expand);
+#endif
+/*! \file */
diff --git a/lib/libc/resolv/res_data.c b/lib/libc/resolv/res_data.c
new file mode 100644 (file)
index 0000000..d301872
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 1995-1999 by 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static const char rcsid[] = "$Id: res_data.c,v 1.5 2007/09/14 05:32:25 marka Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include "port_before.h"
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <ctype.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <res_update.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "port_after.h"
+#ifndef _LIBC
+#undef _res
+#endif
+
+
+const char *_res_opcodes[] = {
+       "QUERY",
+       "IQUERY",
+       "CQUERYM",
+       "CQUERYU",      /*%< experimental */
+       "NOTIFY",       /*%< experimental */
+       "UPDATE",
+       "6",
+       "7",
+       "8",
+       "9",
+       "10",
+       "11",
+       "12",
+       "13",
+       "ZONEINIT",
+       "ZONEREF",
+};
+
+#ifdef BIND_UPDATE
+const char *_res_sectioncodes[] = {
+       "ZONE",
+       "PREREQUISITES",
+       "UPDATE",
+       "ADDITIONAL",
+};
+#endif
+
+#undef _res
+#ifndef __BIND_NOSTATIC
+#ifndef _LIBC
+struct __res_state _res
+# if defined(__BIND_RES_TEXT)
+       = { RES_TIMEOUT, }      /*%< Motorola, et al. */
+# endif
+        ;
+#endif /* !_LIBC */
+
+#if defined(DO_PTHREADS) || defined(__linux)
+#define _res (*__res_state())
+#endif
+
+/* Proto. */
+
+int  res_ourserver_p(const res_state, const struct sockaddr_in *);
+
+int
+res_init(void) {
+       extern int __res_vinit(res_state, int);
+
+       /*
+        * These three fields used to be statically initialized.  This made
+        * it hard to use this code in a shared library.  It is necessary,
+        * now that we're doing dynamic initialization here, that we preserve
+        * the old semantics: if an application modifies one of these three
+        * fields of _res before res_init() is called, res_init() will not
+        * alter them.  Of course, if an application is setting them to
+        * _zero_ before calling res_init(), hoping to override what used
+        * to be the static default, we can't detect it and unexpected results
+        * will follow.  Zero for any of these fields would make no sense,
+        * so one can safely assume that the applications were already getting
+        * unexpected results.
+        *
+        * _res.options is tricky since some apps were known to diddle the bits
+        * before res_init() was first called. We can't replicate that semantic
+        * with dynamic initialization (they may have turned bits off that are
+        * set in RES_DEFAULT).  Our solution is to declare such applications
+        * "broken".  They could fool us by setting RES_INIT but none do (yet).
+        */
+       if (!_res.retrans)
+               _res.retrans = RES_TIMEOUT;
+       if (!_res.retry)
+#ifndef _LIBC
+               _res.retry = 4;
+#else
+               _res.retry = RES_DFLRETRY;
+#endif
+       if (!(_res.options & RES_INIT))
+               _res.options = RES_DEFAULT;
+
+       /*
+        * This one used to initialize implicitly to zero, so unless the app
+        * has set it to something in particular, we can randomize it now.
+        */
+       if (!_res.id)
+               _res.id = res_randomid();
+
+       return (__res_vinit(&_res, 1));
+}
+
+void
+p_query(const u_char *msg) {
+       fp_query(msg, stdout);
+}
+
+void
+fp_query(const u_char *msg, FILE *file) {
+       fp_nquery(msg, PACKETSZ, file);
+}
+
+void
+fp_nquery(const u_char *msg, int len, FILE *file) {
+       if ((_res.options & RES_INIT) == 0U && res_init() == -1)
+               return;
+
+       res_pquery(&_res, msg, len, file);
+}
+
+int
+res_mkquery(int op,                    /*!< opcode of query  */
+           const char *dname,          /*!< domain name  */
+           int class, int type,        /*!< class and type of query  */
+           const u_char *data,         /*!< resource record data  */
+           int datalen,                /*!< length of data  */
+           const u_char *newrr_in,     /*!< new rr for modify or append  */
+           u_char *buf,                /*!< buffer to put query  */
+           int buflen)                 /*!< size of buffer  */
+{
+       if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+               RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+               return (-1);
+       }
+       return (res_nmkquery(&_res, op, dname, class, type,
+                            data, datalen,
+                            newrr_in, buf, buflen));
+}
+
+int
+res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
+       if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+               RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+               return (-1);
+       }
+
+       return (res_nmkupdate(&_res, rrecp_in, buf, buflen));
+}
+
+int
+res_query(const char *name,    /*!< domain name  */
+         int class, int type,  /*!< class and type of query  */
+         u_char *answer,       /*!< buffer to put answer  */
+         int anslen)           /*!< size of answer buffer  */
+{
+       if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+               RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+               return (-1);
+       }
+       return (res_nquery(&_res, name, class, type, answer, anslen));
+}
+
+#ifndef _LIBC
+void
+res_send_setqhook(res_send_qhook hook) {
+       _res.qhook = hook;
+}
+
+void
+res_send_setrhook(res_send_rhook hook) {
+       _res.rhook = hook;
+}
+#endif
+
+int
+res_isourserver(const struct sockaddr_in *inp) {
+       return (res_ourserver_p(&_res, inp));
+}
+
+int
+res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) {
+       if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+               /* errno should have been set by res_init() in this case. */
+               return (-1);
+       }
+
+       return (res_nsend(&_res, buf, buflen, ans, anssiz));
+}
+
+#ifndef _LIBC
+int
+res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key,
+              u_char *ans, int anssiz)
+{
+       if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+               /* errno should have been set by res_init() in this case. */
+               return (-1);
+       }
+
+       return (res_nsendsigned(&_res, buf, buflen, key, ans, anssiz));
+}
+#endif
+
+void
+res_close(void) {
+       res_nclose(&_res);
+}
+
+int
+res_update(ns_updrec *rrecp_in) {
+       if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+               RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+               return (-1);
+       }
+
+       return (res_nupdate(&_res, rrecp_in, NULL));
+}
+
+int
+res_search(const char *name,   /*!< domain name  */
+          int class, int type, /*!< class and type of query  */
+          u_char *answer,      /*!< buffer to put answer  */
+          int anslen)          /*!< size of answer  */
+{
+       if ((_res.options & RES_INIT) == 0U && res_init() == -1) {
+               RES_SET_H_ERRNO(&_res, NETDB_INTERNAL);
+               return (-1);