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