OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [newlib-1.17.0/] [newlib/] [libc/] [sys/] [linux/] [net/] [res_query.c] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.