11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*	$NetBSD: res_query.c,v 1.7 2006/01/24 17:41:25 christos Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1988, 1993
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    The Regents of the University of California.  All rights reserved.
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met:
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    documentation and/or other materials provided with the distribution.
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. All advertising materials mentioning features or use of this software
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    must display the following acknowledgement:
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 	This product includes software developed by the University of
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 	California, Berkeley and its contributors.
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 4. Neither the name of the University nor the names of its contributors
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    may be used to endorse or promote products derived from this software
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *    without specific prior written permission.
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE.
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Portions Copyright (c) 1993 by Digital Equipment Corporation.
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies, and that
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the name of Digital Equipment Corporation not be used in advertising or
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * publicity pertaining to distribution of the document or software without
441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * specific, written prior permission.
451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SOFTWARE.
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies.
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h>
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if defined(LIBC_SCCS) && !defined(lint)
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef notdef
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char sccsid[] = "@(#)res_query.c	8.1 (Berkeley) 6/4/93";
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic const char rcsid[] = "Id: res_query.c,v 1.2.2.3.4.2 2004/03/16 12:34:19 marka Exp";
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project__RCSID("$NetBSD: res_query.c,v 1.7 2006/01/24 17:41:25 christos Exp $");
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* LIBC_SCCS and not lint */
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h>
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/param.h>
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netinet/in.h>
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <arpa/inet.h>
89569fb9887d00104509df79fa77d92e3cf9afe7dbCalin Juravle#include <arpa/nameser.h>
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <ctype.h>
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netdb.h>
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef ANDROID_CHANGES
94ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak#include "resolv_cache.h"
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "resolv_private.h"
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <resolv.h>
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdio.h>
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <stdlib.h>
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <unistd.h>
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <string.h>
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DISABLE_HOST_ALIAS 1
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Options.  Leave them on. */
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef DEBUG
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define DEBUG
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if PACKETSZ > 1024
1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define MAXPACKET	PACKETSZ
1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define MAXPACKET	1024
1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Formulate a normal query, send, and await answer.
1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Returned answer is placed in supplied buffer "answer".
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Perform preliminary check of answer, returning success only
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * if no error is indicated and the answer count is nonzero.
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Return the size of the response on success, -1 on error.
1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Error number is left in H_ERRNO.
1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Caller must parse answer and determine whether it answers the question.
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nquery(res_state statp,
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   const char *name,	/* domain name */
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   int class, int type,	/* class and type of query */
1311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   u_char *answer,	/* buffer to put answer */
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   int anslen)		/* size of answer buffer */
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_char buf[MAXPACKET];
1351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	HEADER *hp = (HEADER *)(void *)answer;
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n;
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_int oflags;
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	oflags = statp->_flags;
1401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectagain:
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	hp->rcode = NOERROR;	/* default */
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (statp->options & RES_DEBUG)
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		printf(";; res_query(%s, %d, %d)\n", name, class, type);
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n = res_nmkquery(statp, QUERY, name, class, type, NULL, 0, NULL,
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 buf, sizeof(buf));
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef RES_USE_EDNS0
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (n > 0 && (statp->_flags & RES_F_EDNS0ERR) == 0 &&
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    (statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U)
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n = res_nopt(statp, n, buf, sizeof(buf), anslen);
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (n <= 0) {
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (statp->options & RES_DEBUG)
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			printf(";; res_query: mkquery failed\n");
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		RES_SET_H_ERRNO(statp, NO_RECOVERY);
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (n);
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	n = res_nsend(statp, buf, n, answer, anslen);
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (n < 0) {
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef RES_USE_EDNS0
1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* if the query choked with EDNS0, retry without EDNS0 */
1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if ((statp->options & (RES_USE_EDNS0|RES_USE_DNSSEC)) != 0U &&
1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		    ((oflags ^ statp->_flags) & RES_F_EDNS0ERR) != 0) {
1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			statp->_flags |= RES_F_EDNS0ERR;
1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (statp->options & RES_DEBUG)
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				printf(";; res_nquery: retry without EDNS0\n");
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			goto again;
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (statp->options & RES_DEBUG)
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			printf(";; res_query: send error\n");
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		RES_SET_H_ERRNO(statp, TRY_AGAIN);
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (n);
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (statp->options & RES_DEBUG)
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			printf(";; rcode = (%s), counts = an:%d ns:%d ar:%d\n",
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			       p_rcode(hp->rcode),
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			       ntohs(hp->ancount),
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			       ntohs(hp->nscount),
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			       ntohs(hp->arcount));
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		switch (hp->rcode) {
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case NXDOMAIN:
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);
1961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
1971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case SERVFAIL:
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			RES_SET_H_ERRNO(statp, TRY_AGAIN);
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case NOERROR:
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			RES_SET_H_ERRNO(statp, NO_DATA);
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case FORMERR:
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case NOTIMP:
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		case REFUSED:
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		default:
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			RES_SET_H_ERRNO(statp, NO_RECOVERY);
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			break;
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (n);
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Formulate a normal query, send, and retrieve answer in supplied buffer.
2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Return the size of the response on success, -1 on error.
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * If enabled, implement search rules until answer or unrecoverable failure
2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * is detected.  Error code, if any, is left in H_ERRNO.
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nsearch(res_state statp,
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    const char *name,	/* domain name */
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    int class, int type,	/* class and type of query */
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    u_char *answer,	/* buffer to put answer */
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    int anslen)		/* size of answer */
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const char *cp, * const *domain;
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	HEADER *hp = (HEADER *)(void *)answer;
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char tmp[NS_MAXDNAME];
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	u_int dots;
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int trailing_dot, ret, saved_herrno;
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int got_nodata = 0, got_servfail = 0, root_on_list = 0;
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int tried_as_is = 0;
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int searched = 0;
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	errno = 0;
2381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	RES_SET_H_ERRNO(statp, HOST_NOT_FOUND);  /* True if we never query. */
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	dots = 0;
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	for (cp = name; *cp != '\0'; cp++)
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		dots += (*cp == '.');
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	trailing_dot = 0;
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (cp > name && *--cp == '.')
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		trailing_dot++;
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* If there aren't any dots, it could be a user-level alias. */
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (!dots && (cp = res_hostalias(statp, name, tmp, sizeof tmp))!= NULL)
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (res_nquery(statp, cp, class, type, answer, anslen));
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * If there are enough dots in the name, let's just give it a
2531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * try 'as is'. The threshold can be set with the "ndots" option.
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * Also, query 'as is', if there is a trailing dot in the name.
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	saved_herrno = -1;
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (dots >= statp->ndots || trailing_dot) {
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ret = res_nquerydomain(statp, name, NULL, class, type,
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					 answer, anslen);
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ret > 0 || trailing_dot)
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (ret);
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		saved_herrno = statp->res_h_errno;
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		tried_as_is++;
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * We do at least one level of search if
2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *	- there is no dot and RES_DEFNAME is set, or
2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *	- there is at least one dot, there is no trailing dot,
2701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 *	  and RES_DNSRCH is set.
2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((!dots && (statp->options & RES_DEFNAMES) != 0U) ||
2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    (dots && !trailing_dot && (statp->options & RES_DNSRCH) != 0U)) {
2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		int done = 0;
2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
276ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak		/* Unfortunately we need to load network-specific info
277c11f6f0f393e472984b5ac2934e2485855a319c9Robert Greenwalt		 * (dns servers, search domains) before
278c11f6f0f393e472984b5ac2934e2485855a319c9Robert Greenwalt		 * the domain stuff is tried.  Will have a better
279c11f6f0f393e472984b5ac2934e2485855a319c9Robert Greenwalt		 * fix after thread pools are used as this will
280c11f6f0f393e472984b5ac2934e2485855a319c9Robert Greenwalt		 * be loaded once for the thread instead of each
281c11f6f0f393e472984b5ac2934e2485855a319c9Robert Greenwalt		 * time a query is tried.
282c11f6f0f393e472984b5ac2934e2485855a319c9Robert Greenwalt		 */
283ea9bf6788144b83cc51c454b2bfe6b980d6e947cSzymon Jakubczak		_resolv_populate_res_for_net(statp);
284c11f6f0f393e472984b5ac2934e2485855a319c9Robert Greenwalt
2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		for (domain = (const char * const *)statp->dnsrch;
2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		     *domain && !done;
2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		     domain++) {
2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			searched = 1;
2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (domain[0][0] == '\0' ||
2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			    (domain[0][0] == '.' && domain[0][1] == '\0'))
2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				root_on_list++;
2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			ret = res_nquerydomain(statp, name, *domain,
2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					       class, type,
2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					       answer, anslen);
2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (ret > 0)
2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return (ret);
2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/*
3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * If no server present, give up.
3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * If name isn't found in this domain,
3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * keep trying higher domains in the search list
3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * (if that's enabled).
3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * On a NO_DATA error, keep trying, otherwise
3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * a wildcard entry of another type could keep us
3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * from finding this entry higher in the domain.
3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * If we get some other error (negative answer or
3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * server failure), then stop searching up,
3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * but try the input name below in case it's
3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * fully-qualified.
3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if (errno == ECONNREFUSED) {
3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				RES_SET_H_ERRNO(statp, TRY_AGAIN);
3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				return (-1);
3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			switch (statp->res_h_errno) {
3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			case NO_DATA:
3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				got_nodata++;
3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* FALLTHROUGH */
3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			case HOST_NOT_FOUND:
3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* keep trying */
3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				break;
3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			case TRY_AGAIN:
3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				if (hp->rcode == SERVFAIL) {
3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					/* try next search element, if any */
3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					got_servfail++;
3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project					break;
3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				}
3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* FALLTHROUGH */
3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			default:
3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				/* anything else implies that we're done */
3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				done++;
3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			}
3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			/* if we got here for some reason other than DNSRCH,
3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 * we only wanted one iteration of the loop, so stop.
3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			 */
3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			if ((statp->options & RES_DNSRCH) == 0U)
3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				done++;
3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * If the query has not already been tried as is then try it
3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * unless RES_NOTLDQUERY is set and there were no dots.
3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if ((dots || !searched || (statp->options & RES_NOTLDQUERY) == 0U) &&
3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    !(tried_as_is || root_on_list)) {
3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		ret = res_nquerydomain(statp, name, NULL, class, type,
3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project				       answer, anslen);
3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (ret > 0)
3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (ret);
3551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* if we got here, we didn't satisfy the search.
3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * if we did an initial full query, return that query's H_ERRNO
3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * (note that we wouldn't be here if that query had succeeded).
3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * else if we ever got a nodata, send that back as the reason.
3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * else send back meaningless H_ERRNO, that being the one from
3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * the last DNSRCH we did.
3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (saved_herrno != -1)
3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		RES_SET_H_ERRNO(statp, saved_herrno);
3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else if (got_nodata)
3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		RES_SET_H_ERRNO(statp, NO_DATA);
3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else if (got_servfail)
3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		RES_SET_H_ERRNO(statp, TRY_AGAIN);
3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (-1);
3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Perform a call on res_query on the concatenation of name and domain,
3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * removing a trailing dot from name if domain is NULL.
3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_nquerydomain(res_state statp,
3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    const char *name,
3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    const char *domain,
3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    int class, int type,	/* class and type of query */
3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    u_char *answer,		/* buffer to put answer */
3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    int anslen)		/* size of answer */
3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{
3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	char nbuf[MAXDNAME];
3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	const char *longname = nbuf;
3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int n, d;
3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef DEBUG
3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (statp->options & RES_DEBUG)
3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		printf(";; res_nquerydomain(%s, %s, %d, %d)\n",
3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		       name, domain?domain:"<Nil>", class, type);
3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (domain == NULL) {
3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Check for trailing '.';
3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * copy without '.' if present.
3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n = strlen(name);
4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (n >= MAXDNAME) {
4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			RES_SET_H_ERRNO(statp, NO_RECOVERY);
4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n--;
4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (n >= 0 && name[n] == '.') {
4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			strncpy(nbuf, name, (size_t)n);
4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			nbuf[n] = '\0';
4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		} else
4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			longname = name;
4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else {
4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		n = strlen(name);
4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		d = strlen(domain);
4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		if (n + d + 1 >= MAXDNAME) {
4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			RES_SET_H_ERRNO(statp, NO_RECOVERY);
4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			return (-1);
4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		}
417cfd8c45725d85f3e2bfccb6b14a9bff59fd5c4c7Dan Albert		snprintf(nbuf, sizeof(nbuf), "%s.%s", name, domain);
4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (res_nquery(statp, longname, class, type, answer, anslen));
4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectconst char *
4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectres_hostalias(const res_state statp, const char *name, char *dst, size_t siz) {
4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (NULL);
4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
426