--- old/usr/src/lib/libdhcpdu/common/rfc2136.c	Tue Nov  4 14:40:11 2014
+++ /dev/null	Tue Nov  4 14:31:37 2014
@@ -1,916 +0,0 @@
-/*
- * CDDL HEADER START
- *
- * The contents of this file are subject to the terms of the
- * Common Development and Distribution License (the "License").
- * You may not use this file except in compliance with the License.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#include	<thread.h>
-#include	<stdlib.h>
-#include	<netdb.h>
-#include	<strings.h>
-#include	<alloca.h>
-#include	<sys/socket.h>
-#include	<netinet/in.h>
-#include	<arpa/inet.h>
-#include	<arpa/nameser.h>
-#include	"res_update.h"
-#include	<stdio.h>
-#include	<errno.h>
-#include	<resolv.h>
-#include	<assert.h>
-#include	<stdarg.h>
-#include	<libnvpair.h>
-
-#define	MAX_RETRIES	5	/* times to loop on TRY_AGAIN errors */
-#define	LEASEMIN	3600	/* minimum lease time allowed by RFC 1531 */
-
-static boolean_t	getNS(char *, struct in_addr *);
-static void		cacheNS(char *, struct in_addr *, int);
-static boolean_t	lookupNS(char *, struct in_addr *);
-static boolean_t	send_update(struct hostent *, struct in_addr *);
-static unsigned short	parse_ushort(const char **);
-static unsigned int	parse_uint(const char **);
-static void		freeupdrecs(ns_updque);
-static void		freehost(struct hostent *);
-static boolean_t	delA(struct __res_state *, char *);
-static boolean_t	delPTR(struct __res_state *, char *, char *);
-static boolean_t	addA(struct __res_state *, char *, struct in_addr);
-static boolean_t	addPTR(struct __res_state *, char *, char *);
-static boolean_t	retry_update(struct __res_state *, ns_updrec *);
-
-extern char		*inet_ntoa_r(struct in_addr, char *);
-
-/*
- *	The parent (calling) thread and the child thread it spawns to do an
- *	update use this structure to rendezvous.  The child thread sets the
- *	``done'' variable to B_TRUE when it's completed its work.  The nusers
- *	variable lets us arbitrate to see who has to clean up (via the
- *	provided childstat_cleanup() function) the dynamically-allocated
- *	structure - last one to wake up loses, and has to do the work.
- */
-struct	childstat {
-	mutex_t		m;
-	cond_t		cv;
-	struct hostent	*hp;
-	boolean_t	synchflag;
-	boolean_t	done;
-	int		ret;
-	int		nusers;
-};
-static void	childstat_cleanup(struct childstat *);
-
-static void	update_thread(void *);
-
-/*
- *	The given environment variable, if present, will contain the name
- *	of a file (or the distinguished values "stdout" and "stderr") into
- *	which we should place the debugging output from this shared object.
- *
- *	The debugging output is basically free-form but uses the dprint()
- *	function to ensure that each message is tagged with its thread ID,
- *	so we have some hope of sorting out later what actually happened.
- */
-static char	env_filetoken[] = "DHCP_DNS_OUTPUT";
-static void	dprint(char *, ...);
-static FILE	*debug_fp;
-
-static boolean_t	dns_config_ok;		/* did res_ninit() work? */
-
-static nvlist_t	*nvl;
-
-/* CSTYLED */
-#pragma init	(init)
-
-/*
- *	This is the shared object startup function, called once when we
- *	are dlopen()ed.
- */
-static void
-init(void)
-{
-	char *cp;
-	struct __res_state res;
-
-	if (cp = getenv(env_filetoken)) {
-		if (strcmp(cp, "stdout") == 0)
-			debug_fp = stdout;
-		else if (strcmp(cp, "stderr") == 0)
-			debug_fp = stderr;
-		else {
-			debug_fp = fopen(cp, "a");
-		}
-		if (debug_fp)
-			(void) setvbuf(debug_fp, NULL, _IOLBF, BUFSIZ);
-	}
-
-	/*
-	 *	Use res_ninit(3RESOLV) to see whether DNS has been configured
-	 *	on the host running this code.  In practice, life must be very
-	 *	bad for res_ninit() to fail.
-	 */
-	(void) memset(&res, 0, sizeof (res));
-	if (res_ninit(&res) == -1) {
-		dprint("res_ninit() failed - dns_config_ok FALSE\n");
-		dns_config_ok = B_FALSE;
-	} else {
-		dprint("res_ninit() succeeded\n");
-		dns_config_ok = B_TRUE;
-	}
-	res_ndestroy(&res);
-}
-
-/*
- *	This is the interface exported to the outside world.  Control over
- *	the hostent structure is assumed to pass to dns_puthostent();  it will
- *	free the associated space when done.
- */
-int
-dns_puthostent(struct hostent *hp, time_t timeout)
-{
-	struct childstat *sp;
-	timestruc_t t;
-	int ret;
-	thread_t tid;
-
-
-	/*
-	 *	Check the consistency of the hostent structure:
-	 *	both the name and address fields should be valid,
-	 *	h_addrtype must be AF_INET, and h_length must be
-	 *	sizeof (struct in_addr);
-	 */
-	if (hp == NULL) {
-		dprint("hp is NULL - return -1\n");
-		return (-1);
-	}
-	if (hp->h_addr_list == NULL) {
-		dprint("h_addr_list is NULL - return -1\n");
-		freehost(hp);
-		return (-1);
-	}
-	if (hp->h_addr_list[0] == NULL) {
-		dprint("h_addr_list is zero-length - return -1\n");
-		freehost(hp);
-		return (-1);
-	}
-	if (hp->h_name == NULL) {
-		dprint("h_name is NULL - return -1\n");
-		freehost(hp);
-		return (-1);
-	}
-	if (hp->h_name[0] == '\0') {
-		dprint("h_name[0] is NUL - return -1\n");
-		freehost(hp);
-		return (-1);
-	}
-	if (hp->h_addrtype != AF_INET) {
-		dprint("h_addrtype (%d) != AF_INET - return -1\n",
-		    hp->h_addrtype);
-		freehost(hp);
-		return (-1);
-	}
-	if (hp->h_length != sizeof (struct in_addr)) {
-		dprint("h_length (%d) != sizeof (struct in_addr) - return -1\n",
-		    hp->h_length);
-		freehost(hp);
-		return (-1);
-	}
-
-	dprint("dns_puthostent(%s, %d)\n", hp->h_name, (int)timeout);
-
-	if (dns_config_ok == B_FALSE) {
-		dprint("dns_config_ok FALSE - return -1\n");
-		freehost(hp);
-		return (-1);
-	}
-
-	if ((sp = malloc(sizeof (struct childstat))) == NULL) {
-		dprint("malloc (sizeof struct childstat) failed\n");
-		freehost(hp);
-		return (-1);
-	}
-
-	/*
-	 *	From this point on, both hp and sp are cleaned up and freed via
-	 *	childstat_cleanup(), with bookkeeping done to see whether the
-	 *	parent thread or the child one should be the one in charge of
-	 *	cleaning up.
-	 */
-	sp->hp = hp;
-
-	if (timeout > 0)
-		sp->synchflag = B_TRUE;
-	else
-		sp->synchflag = B_FALSE;
-	sp->done = B_FALSE;
-	sp->ret = 0;
-	sp->nusers = 1;
-	(void) mutex_init(&sp->m, USYNC_THREAD, 0);
-	(void) cond_init(&sp->cv, USYNC_THREAD, 0);
-	(void) time(&t.tv_sec);
-	t.tv_sec += timeout;
-	t.tv_nsec = 0;
-
-	if (thr_create(NULL, NULL, (void *(*)(void *))update_thread,
-	    (void *) sp, THR_DAEMON|THR_DETACHED, &tid)) {
-		dprint("thr_create failed (errno %d) - return -1\n", errno);
-		childstat_cleanup(sp);
-		return (-1);
-	}
-	else
-		dprint("thread %u created\n", tid);
-
-	if (!sp->done) {	/* we might already have finished */
-		(void) mutex_lock(&sp->m);
-
-		/* if asynchronous, and child still working, just return; */
-		if ((!sp->done) && (timeout == 0)) {
-			sp->nusers--;
-			(void) mutex_unlock(&sp->m);
-			dprint("done 0, timeout 0\n");
-			return (0);
-		}
-
-		/* otherwise, wait for child to finish or time to expire */
-		while (!sp->done)
-			if (cond_timedwait(&sp->cv, &sp->m, &t) == ETIME) {
-				/*
-				 *	Child thread did not return before the
-				 *	timeout.  One might think we could
-				 *		assert(sp->nusers > 1);
-				 *	here, but we can't:  we must protect
-				 *	against this sequence of events:
-				 *		cond_timedwait() times out
-				 *
-				 *		child finishes, grabs mutex,
-				 *		decrements nusers, sets done,
-				 *	    and exits.
-				 *
-				 *		cond_timedwait() reacquires the
-				 *		mutex and returns ETIME
-				 *
-				 *	If this happens, nusers will now be 1,
-				 *	even though cond_timedwait() returned
-				 *	ETIME.
-				 */
-				if (sp->nusers == 1)
-					/* child must have also set done */
-					break;
-				else
-					/* child thread has not returned */
-					sp->nusers--;
-				(void) mutex_unlock(&sp->m);
-				dprint("update for %s timed out\n", hp->h_name);
-				return (0);
-			}
-		assert(sp->done);
-		ret = sp->ret;
-	}
-
-	childstat_cleanup(sp);
-	return (ret);
-}
-
-/*
- *	This worker thread, spawned by dns_puthostent(), is responsible for
- *	seeing that the update work gets done and cleaning up afterward
- *	if necessary.
- */
-static void
-update_thread(void *arg)
-{
-	char *p;
-	int num_updated = 0;
-	struct in_addr ia;
-	struct hostent *hp;
-	struct childstat *sp;
-
-	dprint("update_thread running\n");
-
-	sp = (struct childstat *)arg;
-
-	(void) mutex_lock(&sp->m);
-	/*
-	 *	Paranoia:  if nusers was 0 and we were asked to do a
-	 *	synchronous update, our parent must have incremented
-	 *	it, called cond_timedwait(), timed out, and decremented it,
-	 *	all before we got this far.  In this case, we do nothing
-	 *	except clean up and exit.
-	 */
-	if ((++sp->nusers == 1) && sp->synchflag) {
-		childstat_cleanup(sp);
-		thr_exit(0);
-	}
-
-	(void) mutex_unlock(&sp->m);
-
-	hp = sp->hp;
-
-	/*
-	 *	h_name should be full-qualified;  find the name servers for
-	 *	its domain ...
-	 */
-	for (p = hp->h_name; *p != NULL; p++)
-		if (*p == '.') {
-			if (getNS(++p, &ia)) {
-				char ntoab[INET_ADDRSTRLEN];
-
-				(void) inet_ntoa_r(ia, ntoab);
-				dprint("update for %s goes to %s\n",
-				    hp->h_name, ntoab);
-				/* ... and send the update to one of them. */
-				if (send_update(hp, &ia)) {
-					dprint("send_update succeeded\n");
-					num_updated = 1;
-				} else {
-					dprint("send_update failed\n");
-					num_updated = 0;
-				}
-			} else {
-				dprint("getNS failed\n");
-				num_updated = -1;
-			}
-			break;
-		}
-	dprint("update for %s returning %d\n", hp->h_name, num_updated);
-
-	(void) mutex_lock(&sp->m);
-	if (--sp->nusers == 0) {
-		/* parent timed out and abandoned us - our turn to clean up */
-		childstat_cleanup(sp);
-	} else {
-		sp->done = B_TRUE;
-		sp->ret = num_updated;
-		(void) cond_signal(&sp->cv);
-		(void) mutex_unlock(&sp->m);
-	}
-
-	thr_exit(0);
-}
-
-/*
- *	Find a name server for the supplied domain and return its IP address.
- *	Sadly, in order to do this we have to parse the actual DNS reply
- *	packet - no functions are provided for doing this work for us.
- */
-static boolean_t
-getNS(char *domain, struct in_addr *iap)
-{
-	HEADER *hp;
-	union {
-		HEADER	h;
-		char	buf[NS_PACKETSZ];
-	} abuf;
-	int alen;
-	int count;
-	int retries;
-	unsigned char   name[MAXDNAME];
-	int qdcount, ancount, nscount, arcount;
-	unsigned char *data;
-	unsigned char *m_bound;
-	int type, class, ttl, dlen;
-	struct hostent *ep;
-	unsigned char *NS_data;
-	boolean_t found_NS = B_FALSE;
-	struct __res_state res;
-	extern struct hostent *res_gethostbyname(const char *);
-
-	if (lookupNS(domain, iap)) {
-		dprint("getNS:  found cached IP address for domain %s\n",
-		    domain);
-		return (B_TRUE);
-	}
-	(void) memset(&res, 0, sizeof (res));
-	if (res_ninit(&res) == -1) {
-		dprint("getNS(\"%s\"):  res_ninit failed\n", domain);
-		return (B_FALSE);
-	}
-	for (retries = 0; retries < MAX_RETRIES; retries++) {
-		alen = res_nquery(&res, domain, C_IN, T_NS, (uchar_t *)&abuf,
-		    sizeof (abuf));
-
-		if (alen <= 0) {
-			/*
-			 * Look for indicators from libresolv:res_nsend()
-			 * that we should retry a request.
-			 */
-			if ((errno == ECONNREFUSED) ||
-			    ((h_errno == TRY_AGAIN) && (errno == ETIMEDOUT))) {
-				dprint("getNS retry:  errno %d, h_errno %d\n",
-				    errno, h_errno);
-				continue;
-			} else {
-				dprint("getNS(\"%s\"):  res_nquery failed "
-				    "(h_errno %d)\n", domain, h_errno);
-				res_ndestroy(&res);
-				return (B_FALSE);
-			}
-		}
-	}
-	if (alen <= 0) {
-		dprint("getNS(\"%s\"):  res_nquery failed " "(h_errno %d)\n",
-		    domain, h_errno);
-		res_ndestroy(&res);
-		return (B_FALSE);
-	}
-
-	m_bound = ((unsigned char *)&abuf) + alen;
-
-	hp = (HEADER *)&abuf;
-	data = (unsigned char *)&hp[1];	/* a DNS paradigm - actually abuf.buf */
-
-	qdcount = ntohs(hp->qdcount);
-	ancount = ntohs(hp->ancount);
-	nscount = ntohs(hp->nscount);
-	arcount = ntohs(hp->arcount);
-
-	dprint("getNS(\"%s\"):\n", domain);
-	dprint("\tqdcount %d\n", qdcount);
-	dprint("\tancount %d\n", ancount);
-	dprint("\tnscount %d\n", nscount);
-	dprint("\tarcount %d\n", arcount);
-
-	while (--qdcount >= 0) {
-		dlen = dn_skipname(data, m_bound);
-		if (dlen < 0) {
-			dprint("dn_skipname returned < 0\n");
-			res_ndestroy(&res);
-			return (B_FALSE);
-		}
-		data += dlen + QFIXEDSZ;
-	}
-
-	count = ancount;
-	count += arcount;
-	while (--count >= 0 && data < m_bound) {
-		if ((dlen = dn_expand((unsigned char *) &abuf, m_bound,
-				data, (char *)name, sizeof (name))) < 0) {
-			dprint("dn_expand() dom failed\n");
-			res_ndestroy(&res);
-			return (B_FALSE);
-		}
-		data += dlen;
-		type = parse_ushort((const char **)&data);
-		class = parse_ushort((const char **)&data);
-		ttl = parse_uint((const char **)&data);
-		dlen = parse_ushort((const char **)&data);
-
-		switch (type) {
-			case T_NS:
-				dprint("\ttype T_NS\n");
-				break;
-			case T_CNAME:
-				dprint("\ttype T_CNAME\n");
-				break;
-			case T_A:
-				dprint("\ttype T_A\n");
-				break;
-			case T_SOA:
-				dprint("\ttype T_SOA\n");
-				break;
-			case T_MX:
-				dprint("\ttype T_MX\n");
-				break;
-			case T_TXT:
-				dprint("\ttype T_TXT\n");
-				break;
-			default:
-				dprint("\ttype %d\n", type);
-			}
-			if (class == C_IN)
-				dprint("\tclass C_IN\n");
-			else
-				dprint("\tclass %d\n", class);
-			dprint("\tttl %d secs\n", ttl);
-			dprint("\tlen %d bytes\n", dlen);
-
-		switch (type) {
-		case T_A:
-			(void) memcpy(iap, data, sizeof (struct in_addr));
-			cacheNS(domain, iap, ttl);
-			res_ndestroy(&res);
-			return (B_TRUE);
-
-		case T_NS:
-			found_NS = B_TRUE;
-			NS_data = data;	/* we may need this name below */
-			if (dn_expand((unsigned char *) &abuf, m_bound, data,
-			    (char *)name, sizeof (name)) < 0) {
-				dprint("\tdn_expand() T_NS failed\n");
-				res_ndestroy(&res);
-				return (B_FALSE);
-			}
-			dprint("\tname %s\n", name);
-			break;
-		}
-		data += dlen;
-	}
-	dprint("getNS:  fell through res_nquery results - no A records\n");
-
-	/*
-	 *	The reply contained NS records, but no A records.  Use
-	 *	res_gethostbyname() to get the name server's address
-	 *	via DNS.
-	 */
-	if (found_NS) {
-		if (dn_expand((unsigned char *) &abuf, m_bound, NS_data,
-		    (char *)name, sizeof (name)) < 0) {
-			dprint("\tdn_expand() T_NS failed\n");
-			res_ndestroy(&res);
-			return (B_FALSE);
-		}
-
-		if (ep = res_gethostbyname((const char *)name)) {
-			(void) memcpy(iap, ep->h_addr, sizeof (struct in_addr));
-			cacheNS(domain, iap, ttl);
-			res_ndestroy(&res);
-			return (B_TRUE);
-		} else
-			dprint("getNS:  res_gethostbyname(%s) failed\n", name);
-	} else {
-		dprint("getNS:  reply contained no NS records\n");
-	}
-
-	res_ndestroy(&res);
-	return (B_FALSE);
-}
-
-/*
- *	Cache the <domain, IP address> tuple (which is assumed to not already
- *	be cached) for ttl seconds.
- */
-static void
-cacheNS(char *domain, struct in_addr *iap, int ttl)
-{
-	if (ttl > 0) {
-		time_t now;
-
-		if (nvl == NULL &&
-		    nvlist_alloc(&nvl, NV_UNIQUE_NAME_TYPE, 0) != 0) {
-			dprint("cacheNS:  nvlist_alloc failed\n");
-			return;
-		}
-
-		(void) time(&now);
-		now += ttl;
-		if ((nvlist_add_int32(nvl, domain, iap->s_addr) != 0) ||
-		    (nvlist_add_byte_array(nvl, domain, (uchar_t *)&now,
-			sizeof (now)) != 0)) {
-			dprint("cacheNS:  nvlist_add failed\n");
-			nvlist_free(nvl);
-			nvl = NULL;
-		}
-	} else
-		dprint("cacheNS:  ttl 0 - nothing to cache\n");
-}
-
-/*
- *	See whether the <domain, IP address> tuple has been cached.
- */
-static boolean_t
-lookupNS(char *domain, struct in_addr *iap)
-{
-	int32_t i;
-
-	if (nvlist_lookup_int32(nvl, domain, &i) == 0) {
-		time_t *ttlptr;
-		uint_t nelem = sizeof (*ttlptr);
-
-		if (nvlist_lookup_byte_array(nvl, domain, (uchar_t **)&ttlptr,
-		    &nelem) != 0)
-			return (B_FALSE);
-
-		if (*ttlptr >= time(0)) {	/* still OK to use */
-			iap->s_addr = i;
-			return (B_TRUE);
-		} else {
-			(void) nvlist_remove_all(nvl, domain);
-		}
-	}
-
-	return (B_FALSE);
-}
-
-/*
- *	Do the work of updating DNS to have the <hp->h_name <-> hp->h_addr>
- *	pairing.
- */
-static boolean_t
-send_update(struct hostent *hp, struct in_addr *to_server)
-{
-	char *forfqhost;
-	struct __res_state res;
-	struct in_addr netaddr;
-	char revnamebuf[MAXDNAME];
-
-	(void) memset(&res, 0, sizeof (res));
-	if (res_ninit(&res) == -1) {
-		dprint("send_updated res_ninit failed!");
-		return (B_FALSE);
-	}
-	res.nscount = 1;
-	res.nsaddr.sin_family = AF_INET;
-	res.nsaddr.sin_port = htons(NAMESERVER_PORT);
-	res.nsaddr.sin_addr.s_addr = to_server->s_addr;
-
-	/* If debugging output desired, then ask resolver to do it, too */
-	if (debug_fp != NULL)
-		res.options |= RES_DEBUG;
-
-	if (strchr(hp->h_name, '.') == NULL) {
-		dprint("send_update handed non-FQDN:  %s\n", hp->h_name);
-		res_ndestroy(&res);
-		return (B_FALSE);
-	}
-	forfqhost = hp->h_name;
-
-	/* Construct the fully-qualified name for PTR record updates */
-	/* LINTED - alignment */
-	netaddr.s_addr = ((struct in_addr *)hp->h_addr)->s_addr;
-	(void) snprintf(revnamebuf, sizeof (revnamebuf),
-	    "%u.%u.%u.%u.in-addr.ARPA",
-	    netaddr.S_un.S_un_b.s_b4, netaddr.S_un.S_un_b.s_b3,
-	    netaddr.S_un.S_un_b.s_b2, netaddr.S_un.S_un_b.s_b1);
-	dprint("send_update %s:  revname %s\n", hp->h_name, revnamebuf);
-
-	/*
-	 *	The steps in doing an update:
-	 *		-  delete any A records
-	 *		-  delete any PTR records
-	 *		-  add an A record
-	 *		-  add a PTR record
-	 */
-
-	if (!delA(&res, forfqhost) ||
-	    !delPTR(&res, forfqhost, revnamebuf) ||
-	    !addA(&res, forfqhost, netaddr) ||
-	    !addPTR(&res, forfqhost, revnamebuf)) {
-		res_ndestroy(&res);
-		return (B_FALSE);
-	}
-	res_ndestroy(&res);
-	return (B_TRUE);
-}
-
-/* delete A records for this fully-qualified name */
-static boolean_t
-delA(struct __res_state *resp, char *fqdn)
-{
-	ns_updque q;
-	ns_updrec *updreqp;
-
-	INIT_LIST(q);
-	updreqp = res_mkupdrec(S_UPDATE, fqdn, C_IN, T_A, 0);
-	if (updreqp == NULL) {
-		dprint("res_mkupdrec (del A) failed\n");
-		return (B_FALSE);
-	}
-	updreqp->r_opcode = DELETE;
-	updreqp->r_data = NULL;
-	updreqp->r_size = 0;
-	APPEND(q, updreqp, r_link);
-	if (retry_update(resp, HEAD(q)) != 1) {
-		dprint("res_nupdate (del A) failed - errno %d, h_errno %d\n",
-		    errno, h_errno);
-		freeupdrecs(q);
-		return (B_FALSE);
-	}
-	freeupdrecs(q);
-	return (B_TRUE);
-}
-
-/* delete PTR records for this address */
-static boolean_t
-delPTR(struct __res_state *resp, char *fqdn, char *revname)
-{
-	ns_updque q;
-	ns_updrec *updreqp;
-
-	INIT_LIST(q);
-	updreqp = res_mkupdrec(S_UPDATE, revname, C_IN, T_PTR, 0);
-	if (updreqp == NULL) {
-		dprint("res_mkupdrec (del PTR) failed\n");
-		return (B_FALSE);
-	}
-	updreqp->r_opcode = DELETE;
-	updreqp->r_data = (unsigned char *)fqdn;
-	updreqp->r_size = strlen(fqdn);
-	APPEND(q, updreqp, r_link);
-	if (retry_update(resp, HEAD(q)) != 1) {
-		dprint("res_nupdate (del PTR) failed - errno %d, h_errno %d\n",
-		    errno, h_errno);
-		freeupdrecs(q);
-		return (B_FALSE);
-	}
-	freeupdrecs(q);
-	return (B_TRUE);
-}
-
-/* add an A record for this fqdn <-> addr pair */
-static boolean_t
-addA(struct __res_state *resp, char *fqdn, struct in_addr na)
-{
-	ns_updque q;
-	ns_updrec *prereqp, *updreqp;
-	int ttl = LEASEMIN;
-	char ntoab[INET_ADDRSTRLEN];
-
-	INIT_LIST(q);
-	prereqp = res_mkupdrec(S_PREREQ, fqdn, C_IN, T_A, 0);
-	if (prereqp == NULL) {
-		dprint("res_mkupdrec (add A PREREQ) failed\n");
-		return (B_FALSE);
-	}
-	prereqp->r_opcode = NXRRSET;
-	prereqp->r_data = NULL;
-	prereqp->r_size = 0;
-	APPEND(q, prereqp, r_link);
-	updreqp = res_mkupdrec(S_UPDATE, fqdn, C_IN, T_A, ttl);
-	if (updreqp == NULL) {
-		dprint("res_mkupdrec (add A UPDATE) failed\n");
-		freeupdrecs(q);
-		return (B_FALSE);
-	}
-
-	(void) inet_ntoa_r(na, ntoab);
-	updreqp->r_opcode = ADD;
-	updreqp->r_data = (unsigned char *)ntoab;
-	updreqp->r_size = strlen(ntoab);
-	APPEND(q, updreqp, r_link);
-	if (retry_update(resp, HEAD(q)) != 1) {
-		dprint("res_nupdate (ADD A) failed - errno %d, h_errno %d\n",
-		    errno, h_errno);
-		freeupdrecs(q);
-		return (B_FALSE);
-	}
-	freeupdrecs(q);
-	return (B_TRUE);
-}
-
-/* add a PTR record for this fqdn <-> address pair */
-static boolean_t
-addPTR(struct __res_state *resp, char *fqdn, char *revname)
-{
-	ns_updque q;
-	ns_updrec *prereqp, *updreqp;
-	int ttl = LEASEMIN;
-
-	INIT_LIST(q);
-	prereqp = res_mkupdrec(S_UPDATE, revname, C_IN, T_PTR, 0);
-	if (prereqp == NULL) {
-		dprint("res_mkupdrec (add PTR DELETE) failed\n");
-		return (B_FALSE);
-	}
-	prereqp->r_opcode = DELETE;
-	prereqp->r_data = NULL;
-	prereqp->r_size = 0;
-	APPEND(q, prereqp, r_link);
-	updreqp = res_mkupdrec(S_UPDATE, revname, C_IN, T_PTR, ttl);
-	if (updreqp == NULL) {
-		dprint("res_mkupdrec (add PTR ADD) failed\n");
-		freeupdrecs(q);
-		return (B_FALSE);
-	}
-	updreqp->r_opcode = ADD;
-	updreqp->r_data = (unsigned char *)fqdn;
-	updreqp->r_size = strlen(fqdn);
-	APPEND(q, updreqp, r_link);
-	if (retry_update(resp, HEAD(q)) != 1) {
-		dprint("res_nupdate (ADD PTR) failed - errno %d, h_errno %d\n",
-		    errno, h_errno);
-		freeupdrecs(q);
-		return (B_FALSE);
-	}
-	freeupdrecs(q);
-
-	return (B_TRUE);
-}
-
-/* retry an update request when appropriate */
-static boolean_t
-retry_update(struct __res_state *resp, ns_updrec *h)
-{
-	int retries;
-
-	for (retries = 0; retries < MAX_RETRIES; retries++)
-		if (res_nupdate(resp, h, NULL) == 1) {
-			return (B_TRUE);
-		} else {
-			/*
-			 * Look for indicators from libresolv:res_nsend()
-			 * that we should retry a request.
-			 */
-			if ((errno == ECONNREFUSED) ||
-			    ((h_errno == TRY_AGAIN) && (errno == ETIMEDOUT))) {
-				dprint("retry_update - errno %d, h_errno %d\n",
-				    errno, h_errno);
-				continue;
-			} else
-				return (B_FALSE);
-		}
-
-	return (B_FALSE);
-}
-
-static void
-freeupdrecs(ns_updque q)
-{
-	while (!EMPTY(q)) {
-		ns_updrec *tmp;
-
-		tmp = HEAD(q);
-		UNLINK(q, tmp, r_link);
-		res_freeupdrec(tmp);
-	}
-}
-
-/*
- *	Parse a 16-bit quantity from a DNS reply packet.
- */
-static unsigned short
-parse_ushort(const char **pp)
-{
-	const uchar_t	*p = (const uchar_t *)*pp;
-	unsigned short  val;
-
-	val = (p[0] << 8) | p[1];
-	*pp += 2;
-	return (val);
-}
-
-
-/*
- *	Parse a 32-bit quantity from a DNS reply packet.
- */
-static unsigned int
-parse_uint(const char **pp)
-{
-	const uchar_t	*p = (const uchar_t *)*pp;
-	unsigned int   val;
-
-	val =  ((uint_t)p[0] << 24) | ((uint_t)p[1] << 16) |
-	    ((uint_t)p[2] << 8) | (uint_t)p[3];
-	*pp += 4;
-	return (val);
-}
-
-/*
- *	Clean up a childstat structure's synchronization variables and free
- *	the allocated memory.
- */
-static void
-childstat_cleanup(struct childstat *sp)
-{
-	(void) cond_destroy(&sp->cv);
-	(void) mutex_destroy(&sp->m);
-	freehost(sp->hp);
-	free(sp);
-}
-
-/*
- *	Format and print a debug message, prepending the thread ID of the
- *	thread logging the message.
- */
-/* PRINTFLIKE1 */
-static void
-dprint(char *format, ...)
-{
-	va_list ap;
-
-	va_start(ap, format);
-	if (debug_fp) {
-		(void) fprintf(debug_fp, "%u:  ", thr_self());
-		(void) vfprintf(debug_fp, format, ap);
-		va_end(ap);
-	}
-}
-
-static void
-freehost(struct hostent *hp)
-{
-	free(hp->h_addr);
-	free(hp->h_addr_list);
-	free(hp->h_name);
-	free(hp);
-}
