1d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
2d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Copyright (c) 1988, 1993
3d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    The Regents of the University of California.  All rights reserved.
4d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
5d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Portions copyright (c) 1999, 2000
6d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Intel Corporation.
7d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * All rights reserved.
8d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
9d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Redistribution and use in source and binary forms, with or without
10d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * modification, are permitted provided that the following conditions
11d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * are met:
12d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
13d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 1. Redistributions of source code must retain the above copyright
14d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer.
15d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
16d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 2. Redistributions in binary form must reproduce the above copyright
17d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    notice, this list of conditions and the following disclaimer in the
18d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    documentation and/or other materials provided with the distribution.
19d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
20d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 3. All advertising materials mentioning features or use of this software
21d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    must display the following acknowledgement:
22d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
23d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    This product includes software developed by the University of
24d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    California, Berkeley, Intel Corporation, and its contributors.
25d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
26d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * 4. Neither the name of University, Intel Corporation, or their respective
27d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    contributors may be used to endorse or promote products derived from
28d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *    this software without specific prior written permission.
29d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
30d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THIS SOFTWARE IS PROVIDED BY THE REGENTS, INTEL CORPORATION AND
31d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
32d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
33d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS,
34d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * INTEL CORPORATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
35d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
42d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
43d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
44d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
45d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Portions Copyright (c) 1993 by Digital Equipment Corporation.
46d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
47d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Permission to use, copy, modify, and distribute this software for any
48d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * purpose with or without fee is hereby granted, provided that the above
49d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * copyright notice and this permission notice appear in all copies, and that
50d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * the name of Digital Equipment Corporation not be used in advertising or
51d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * publicity pertaining to distribution of the document or software without
52d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * specific, written prior permission.
53d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
54d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
55d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
56d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
57d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
58d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
59d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
60d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
61d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * SOFTWARE.
62d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
63d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
64d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
65d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Portions Copyright (c) 1996 by Internet Software Consortium.
66d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
67d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Permission to use, copy, modify, and distribute this software for any
68d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * purpose with or without fee is hereby granted, provided that the above
69d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * copyright notice and this permission notice appear in all copies.
70d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
71d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
72d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
73d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
74d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
75d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
76d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
77d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
78d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * SOFTWARE.
79d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
80d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
81d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#if defined(LIBC_SCCS) && !defined(lint)
82d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
83d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic char orig_rcsid = "From: Id: res_query.c,v 8.14 1997/06/09 17:47:05 halley Exp $";
84d7ce700605e1af0e455e31ec11f19ff21d26b525darylmstatic char rcsid[] = "$Id: res_query.c,v 1.1.1.1 2003/11/19 01:51:38 kyu3 Exp $";
85d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif /* LIBC_SCCS and not lint */
86d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
87d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <sys/types.h>
88d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <sys/param.h>
89d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <netinet/in.h>
90d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <arpa/inet.h>
91d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <arpa/nameser.h>
92d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <ctype.h>
93d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <errno.h>
94d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <netdb.h>
95d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <resolv.h>
96d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <stdio.h>
97d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <stdlib.h>
98d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include <string.h>
99d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
100d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#include "res_config.h"
101d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
102d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#if PACKETSZ > 1024
103d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define MAXPACKET   PACKETSZ
104d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#else
105d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#define MAXPACKET   1024
106d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
107d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
108d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
109d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Formulate a normal query, send, and await answer.
110d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Returned answer is placed in supplied buffer "answer".
111d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Perform preliminary check of answer, returning success only
112d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * if no error is indicated and the answer count is nonzero.
113d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Return the size of the response on success, -1 on error.
114d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Error number is left in h_errno.
115d7ce700605e1af0e455e31ec11f19ff21d26b525darylm *
116d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Caller must parse answer and determine whether it answers the question.
117d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
118d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
119d7ce700605e1af0e455e31ec11f19ff21d26b525darylmres_query(
120d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    const char *name,   /* domain name */
121d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int class,          /* class of query */
122d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int type,           /* type of query */
123d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    u_char *answer,     /* buffer to put answer */
124d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int anslen          /* size of answer buffer */
125d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    )
126d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
127d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    u_char buf[MAXPACKET];
128d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    HEADER *hp = (HEADER *) answer;
129d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int n;
130d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
131d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    hp->rcode = NOERROR;    /* default */
132d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
133d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
134d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        h_errno = NETDB_INTERNAL;
135d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (-1);
136d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
137d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifdef DEBUG
138d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (_res.options & RES_DEBUG)
139d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        printf(";; res_query(%s, %d, %d)\n", name, class, type);
140d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
141d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
142d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
143d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            buf, sizeof(buf));
144d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (n <= 0) {
145d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifdef DEBUG
146d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (_res.options & RES_DEBUG)
147d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            printf(";; res_query: mkquery failed\n");
148d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
149d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        h_errno = NO_RECOVERY;
150d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (n);
151d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
152d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    n = res_send(buf, n, answer, anslen);
153d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (n < 0) {
154d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifdef DEBUG
155d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (_res.options & RES_DEBUG)
156d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            printf(";; res_query: send error\n");
157d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
158d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        h_errno = TRY_AGAIN;
159d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (n);
160d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
161d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
162d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
163d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifdef DEBUG
164d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (_res.options & RES_DEBUG)
165d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            printf(";; rcode = %d, ancount=%d\n", hp->rcode,
166d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                ntohs(hp->ancount));
167d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
168d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        switch (hp->rcode) {
169d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        case NXDOMAIN:
170d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            h_errno = HOST_NOT_FOUND;
171d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            break;
172d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        case SERVFAIL:
173d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            h_errno = TRY_AGAIN;
174d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            break;
175d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        case NOERROR:
176d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            h_errno = NO_DATA;
177d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            break;
178d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        case FORMERR:
179d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        case NOTIMP:
180d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        case REFUSED:
181d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        default:
182d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            h_errno = NO_RECOVERY;
183d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            break;
184d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        }
185d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (-1);
186d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
187d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    return (n);
188d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
189d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
190d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
191d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Formulate a normal query, send, and retrieve answer in supplied buffer.
192d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Return the size of the response on success, -1 on error.
193d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * If enabled, implement search rules until answer or unrecoverable failure
194d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * is detected.  Error code, if any, is left in h_errno.
195d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
196d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
197d7ce700605e1af0e455e31ec11f19ff21d26b525darylmres_search(
198d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    const char *name,   /* domain name */
199d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int class,          /* class of query */
200d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int type,           /* type of query */
201d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    u_char *answer,     /* buffer to put answer */
202d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int anslen          /* size of answer */
203d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    )
204d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
205d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    const char *cp, * const *domain;
206d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    HEADER *hp = (HEADER *) answer;
207d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    u_int dots;
208d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int trailing_dot, ret, saved_herrno;
209d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
210d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
211d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
212d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        h_errno = NETDB_INTERNAL;
213d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (-1);
214d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
215d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    errno = 0;
216d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    h_errno = HOST_NOT_FOUND;   /* default, if we never query */
217d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    dots = 0;
218d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    for (cp = name; *cp; cp++)
219d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        dots += (*cp == '.');
220d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    trailing_dot = 0;
221d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (cp > name && *--cp == '.')
222d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        trailing_dot++;
223d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
224d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    /* If there aren't any dots, it could be a user-level alias */
225d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (!dots && (cp = hostalias(name)) != NULL)
226d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (res_query(cp, class, type, answer, anslen));
227d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
228d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    /*
229d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * If there are dots in the name already, let's just give it a try
230d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * 'as is'.  The threshold can be set with the "ndots" option.
231d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     */
232d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    saved_herrno = -1;
233d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (dots >= _res.ndots) {
234d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ret = res_querydomain(name, NULL, class, type, answer, anslen);
235d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (ret > 0)
236d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            return (ret);
237d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        saved_herrno = h_errno;
238d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        tried_as_is++;
239d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
240d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
241d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    /*
242d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * We do at least one level of search if
243d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     *  - there is no dot and RES_DEFNAME is set, or
244d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     *  - there is at least one dot, there is no trailing dot,
245d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     *    and RES_DNSRCH is set.
246d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     */
247d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if ((!dots && (_res.options & RES_DEFNAMES)) ||
248d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        (dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
249d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        int done = 0;
250d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
251d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        for (domain = (const char * const *)_res.dnsrch;
252d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             *domain && !done;
253d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             domain++) {
254d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
255d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            ret = res_querydomain(name, *domain, class, type,
256d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                          answer, anslen);
257d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            if (ret > 0)
258d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                return (ret);
259d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
260d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            /*
261d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * If no server present, give up.
262d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * If name isn't found in this domain,
263d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * keep trying higher domains in the search list
264d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * (if that's enabled).
265d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * On a NO_DATA error, keep trying, otherwise
266d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * a wildcard entry of another type could keep us
267d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * from finding this entry higher in the domain.
268d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * If we get some other error (negative answer or
269d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * server failure), then stop searching up,
270d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * but try the input name below in case it's
271d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * fully-qualified.
272d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             */
273d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            if (errno == ECONNREFUSED) {
274d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                h_errno = TRY_AGAIN;
275d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                return (-1);
276d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            }
277d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
278d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            switch (h_errno) {
279d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            case NO_DATA:
280d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                got_nodata++;
281d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                /* FALLTHROUGH */
282d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            case HOST_NOT_FOUND:
283d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                /* keep trying */
284d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                break;
285d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            case TRY_AGAIN:
286d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                if (hp->rcode == SERVFAIL) {
287d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                    /* try next search element, if any */
288d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                    got_servfail++;
289d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                    break;
290d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                }
291d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                /* FALLTHROUGH */
292d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            default:
293d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                /* anything else implies that we're done */
294d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                done++;
295d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            }
296d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
297d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            /* if we got here for some reason other than DNSRCH,
298d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             * we only wanted one iteration of the loop, so stop.
299d7ce700605e1af0e455e31ec11f19ff21d26b525darylm             */
300d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            if (!(_res.options & RES_DNSRCH))
301d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                done++;
302d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        }
303d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
304d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
305d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    /*
306d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * If we have not already tried the name "as is", do that now.
307d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * note that we do this regardless of how many dots were in the
308d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * name or whether it ends with a dot unless NOTLDQUERY is set.
309d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     */
310d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {
311d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        ret = res_querydomain(name, NULL, class, type, answer, anslen);
312d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (ret > 0)
313d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            return (ret);
314d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
315d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
316d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    /* if we got here, we didn't satisfy the search.
317d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * if we did an initial full query, return that query's h_errno
318d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * (note that we wouldn't be here if that query had succeeded).
319d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * else if we ever got a nodata, send that back as the reason.
320d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * else send back meaningless h_errno, that being the one from
321d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     * the last DNSRCH we did.
322d7ce700605e1af0e455e31ec11f19ff21d26b525darylm     */
323d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (saved_herrno != -1)
324d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        h_errno = saved_herrno;
325d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    else if (got_nodata)
326d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        h_errno = NO_DATA;
327d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    else if (got_servfail)
328d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        h_errno = TRY_AGAIN;
329d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    return (-1);
330d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
331d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
332d7ce700605e1af0e455e31ec11f19ff21d26b525darylm/*
333d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * Perform a call on res_query on the concatenation of name and domain,
334d7ce700605e1af0e455e31ec11f19ff21d26b525darylm * removing a trailing dot from name if domain is NULL.
335d7ce700605e1af0e455e31ec11f19ff21d26b525darylm */
336d7ce700605e1af0e455e31ec11f19ff21d26b525darylmint
337d7ce700605e1af0e455e31ec11f19ff21d26b525darylmres_querydomain(
338d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    const char *name,
339d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    const char *domain,
340d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int class,      /* class of query */
341d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int type,       /* type of query */
342d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    u_char *answer, /* buffer to put answer */
343d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int anslen      /* size of answer */
344d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    )
345d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
346d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    char nbuf[MAXDNAME];
347d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    const char *longname = nbuf;
348d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    int n, d;
349d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
350d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
351d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        h_errno = NETDB_INTERNAL;
352d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (-1);
353d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
354d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifdef DEBUG
355d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (_res.options & RES_DEBUG)
356d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        printf(";; res_querydomain(%s, %s, %d, %d)\n",
357d7ce700605e1af0e455e31ec11f19ff21d26b525darylm               name, domain?domain:"<Nil>", class, type);
358d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
359d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (domain == NULL) {
360d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        /*
361d7ce700605e1af0e455e31ec11f19ff21d26b525darylm         * Check for trailing '.';
362d7ce700605e1af0e455e31ec11f19ff21d26b525darylm         * copy without '.' if present.
363d7ce700605e1af0e455e31ec11f19ff21d26b525darylm         */
364d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        n = (int)strlen(name);
365d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (n >= MAXDNAME) {
366d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            h_errno = NO_RECOVERY;
367d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            return (-1);
368d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        }
369d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        n--;
370d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (n >= 0 && name[n] == '.') {
371d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            strncpy(nbuf, name, n);
372d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            nbuf[n] = '\0';
373d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        } else
374d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            longname = name;
375d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    } else {
376d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        n = (int)strlen(name);
377d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        d = (int)strlen(domain);
378d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (n + d + 1 >= MAXDNAME) {
379d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            h_errno = NO_RECOVERY;
380d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            return (-1);
381d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        }
382d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        sprintf(nbuf, "%s.%s", name, domain);
383d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
384d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    return (res_query(longname, class, type, answer, anslen));
385d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
386d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
387d7ce700605e1af0e455e31ec11f19ff21d26b525darylmconst char *
388d7ce700605e1af0e455e31ec11f19ff21d26b525darylmhostalias(
389d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    const char *name
390d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    )
391d7ce700605e1af0e455e31ec11f19ff21d26b525darylm{
392d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    register char *cp1, *cp2;
393d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    FILE *fp;
394d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    char *file;
395d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    char buf[BUFSIZ];
396d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    static char abuf[MAXDNAME];
397d7ce700605e1af0e455e31ec11f19ff21d26b525darylm
398d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (_res.options & RES_NOALIASES)
399d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (NULL);
400d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#ifdef _ORG_FREEBSD_
401d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (issetugid())
402d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (NULL);
403d7ce700605e1af0e455e31ec11f19ff21d26b525darylm#endif
404d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    file = getenv("HOSTALIASES");
405d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    if (file == NULL || (fp = fopen(file, "r")) == NULL)
406d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        return (NULL);
407d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    setbuf(fp, NULL);
408d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    buf[sizeof(buf) - 1] = '\0';
409d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    while (fgets(buf, sizeof(buf), fp)) {
410d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
411d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            ;
412d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (!*cp1)
413d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            break;
414d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        *cp1 = '\0';
415d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        if (!strcasecmp(buf, name)) {
416d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            while (isspace(*++cp1))
417d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                ;
418d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            if (!*cp1)
419d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                break;
420d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
421d7ce700605e1af0e455e31ec11f19ff21d26b525darylm                ;
422d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            abuf[sizeof(abuf) - 1] = *cp2 = '\0';
423d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            strncpy(abuf, cp1, sizeof(abuf) - 1);
424d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            fclose(fp);
425d7ce700605e1af0e455e31ec11f19ff21d26b525darylm            return (abuf);
426d7ce700605e1af0e455e31ec11f19ff21d26b525darylm        }
427d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    }
428d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    fclose(fp);
429d7ce700605e1af0e455e31ec11f19ff21d26b525darylm    return (NULL);
430d7ce700605e1af0e455e31ec11f19ff21d26b525darylm}
431