Libinfo-278.tar.gz
[apple/libinfo.git] / dns.subproj / gethnamaddr.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.1 (the "License"). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
12 * this file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
20 * under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24 /*
25 * ++Copyright++ 1985, 1988, 1993
26 * -
27 * Copyright (c) 1985, 1988, 1993
28 * The Regents of the University of California. All rights reserved.
29 *
30 * Redistribution and use in source and binary forms, with or without
31 * modification, are permitted provided that the following conditions
32 * are met:
33 * 1. Redistributions of source code must retain the above copyright
34 * notice, this list of conditions and the following disclaimer.
35 * 2. Redistributions in binary form must reproduce the above copyright
36 * notice, this list of conditions and the following disclaimer in the
37 * documentation and/or other materials provided with the distribution.
38 * 3. All advertising materials mentioning features or use of this software
39 * must display the following acknowledgement:
40 * This product includes software developed by the University of
41 * California, Berkeley and its contributors.
42 * 4. Neither the name of the University nor the names of its contributors
43 * may be used to endorse or promote products derived from this software
44 * without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 * -
58 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
59 *
60 * Permission to use, copy, modify, and distribute this software for any
61 * purpose with or without fee is hereby granted, provided that the above
62 * copyright notice and this permission notice appear in all copies, and that
63 * the name of Digital Equipment Corporation not be used in advertising or
64 * publicity pertaining to distribution of the document or software without
65 * specific, written prior permission.
66 *
67 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
68 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
69 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
70 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
71 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
72 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
73 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
74 * SOFTWARE.
75 * -
76 * --Copyright--
77 */
78
79 #if defined(LIBC_SCCS) && !defined(lint)
80 static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
81 static char rcsid[] = "$Id: gethnamaddr.c,v 1.9 2004/10/07 17:33:33 majka Exp $";
82 #endif /* LIBC_SCCS and not lint */
83
84 #include <sys/param.h>
85 #include <sys/socket.h>
86 #include <netinet/in.h>
87 #include <arpa/inet.h>
88 #include <arpa/nameser8_compat.h>
89
90 #include <stdio.h>
91 #include <stdlib.h>
92 #include <netdb.h>
93 #include <resolv8_compat.h>
94 #include <ctype.h>
95 #include <errno.h>
96 #include <syslog.h>
97
98 #ifndef LOG_AUTH
99 # define LOG_AUTH 0
100 #endif
101
102 #define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */
103
104 #if defined(BSD) && (BSD >= 199103)
105 # include <string.h>
106 #else
107 # include "portability.h"
108 #endif
109 #if defined(USE_OPTIONS_H)
110 # include "options.h"
111 #endif
112
113 #define MAXALIASES 35
114 #define MAXADDRS 35
115 #define MAXHOSTBUF 8*1024
116
117 static const char AskedForGot[] =
118 "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
119
120 static char *h_addr_ptrs[MAXADDRS + 1];
121 #ifdef NOTDEF
122 static struct hostent *gethostbyname_ipv4 __P((const char *));
123 #endif
124 static struct hostent host;
125 static char *host_aliases[MAXALIASES];
126 static char *hostbuf = NULL;
127 static struct in_addr host_addr;
128 static FILE *hostf = NULL;
129 static int stayopen = 0;
130
131 #ifdef RESOLVSORT
132 static void addrsort __P((char **, int));
133 #endif
134
135 #if PACKETSZ > 1024
136 #define MAXPACKET PACKETSZ
137 #else
138 #define MAXPACKET 1024
139 #endif
140
141 typedef union {
142 HEADER hdr;
143 u_char buf[MAXPACKET];
144 } querybuf;
145
146 typedef union {
147 int32_t al;
148 char ac;
149 } align;
150
151 extern int h_errno;
152
153 #ifdef DEBUG
154 static void
155 dprintf(msg, num)
156 char *msg;
157 int num;
158 {
159 if (_res.options & RES_DEBUG) {
160 int save = errno;
161
162 printf(msg, num);
163 errno = save;
164 }
165 }
166 #else
167 # define dprintf(msg, num) /*nada*/
168 #endif
169
170 static struct hostent *
171 getanswer(answer, anslen, qname, qclass, qtype)
172 const querybuf *answer;
173 int anslen;
174 const char *qname;
175 int qclass, qtype;
176 {
177 register const HEADER *hp;
178 register const u_char *cp;
179 register int n;
180 const u_char *eom;
181 char *bp, **ap, **hap;
182 int type, class, buflen, ancount, qdcount;
183 int haveanswer, had_error;
184 int toobig = 0;
185 char tbuf[MAXDNAME+1];
186 const char *tname;
187
188 if (hostbuf == NULL) {
189 hostbuf = malloc(MAXHOSTBUF);
190 if (hostbuf == NULL)
191 return (NULL);
192 }
193 buflen = MAXHOSTBUF;
194
195 tname = qname;
196 host.h_name = NULL;
197 eom = answer->buf + anslen;
198 /*
199 * find first satisfactory answer
200 */
201 hp = &answer->hdr;
202 ancount = ntohs(hp->ancount);
203 qdcount = ntohs(hp->qdcount);
204 bp = hostbuf;
205 cp = answer->buf + HFIXEDSZ;
206 if (qdcount != 1) {
207 h_errno = NO_RECOVERY;
208 return (NULL);
209 }
210 if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) {
211 h_errno = NO_RECOVERY;
212 return (NULL);
213 }
214 cp += n + QFIXEDSZ;
215 if (qtype == T_A) {
216 /* res_send() has already verified that the query name is the
217 * same as the one we sent; this just gets the expanded name
218 * (i.e., with the succeeding search-domain tacked on).
219 */
220 n = strlen(bp) + 1; /* for the \0 */
221 host.h_name = bp;
222 bp += n;
223 buflen -= n;
224 /* The qname can be abbreviated, but h_name is now absolute. */
225 qname = host.h_name;
226 }
227 ap = host_aliases;
228 *ap = NULL;
229 host.h_aliases = host_aliases;
230 hap = h_addr_ptrs;
231 *hap = NULL;
232 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
233 host.h_addr_list = h_addr_ptrs;
234 #endif
235 haveanswer = 0;
236 had_error = 0;
237 while (ancount-- > 0 && cp < eom && !had_error) {
238 n = dn_expand(answer->buf, eom, cp, bp, buflen);
239 if (n < 0) {
240 had_error++;
241 continue;
242 }
243 cp += n; /* name */
244 type = _getshort(cp);
245 cp += INT16SZ; /* type */
246 class = _getshort(cp);
247 cp += INT16SZ + INT32SZ; /* class, TTL */
248 n = _getshort(cp);
249 cp += INT16SZ; /* len */
250 if (class != qclass) {
251 /* XXX - debug? syslog? */
252 cp += n;
253 continue; /* XXX - had_error++ ? */
254 }
255 if (qtype == T_A && type == T_CNAME) {
256 if (ap >= &host_aliases[MAXALIASES-1])
257 continue;
258 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
259 if (n < 0) {
260 had_error++;
261 continue;
262 }
263 cp += n;
264 if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
265 syslog(LOG_NOTICE|LOG_AUTH,
266 "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
267 host.h_name, bp);
268 continue; /* XXX - had_error++ ? */
269 }
270 /* Store alias. */
271 *ap++ = bp;
272 n = strlen(bp) + 1; /* for the \0 */
273 bp += n;
274 buflen -= n;
275 /* Get canonical name. */
276 n = strlen(tbuf) + 1; /* for the \0 */
277 if (n > buflen) {
278 had_error++;
279 continue;
280 }
281 strcpy(bp, tbuf);
282 host.h_name = bp;
283 bp += n;
284 buflen -= n;
285 continue;
286 }
287 if (qtype == T_PTR && type == T_CNAME) {
288 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
289 if (n < 0) {
290 had_error++;
291 continue;
292 }
293 cp += n;
294 /* Get canonical name. */
295 n = strlen(tbuf) + 1; /* for the \0 */
296 if (n > buflen) {
297 had_error++;
298 continue;
299 }
300 strcpy(bp, tbuf);
301 tname = bp;
302 bp += n;
303 buflen -= n;
304 continue;
305 }
306 if (type != qtype) {
307 syslog(LOG_NOTICE|LOG_AUTH,
308 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
309 qname, p_class(qclass), p_type(qtype),
310 p_type(type));
311 cp += n;
312 continue; /* XXX - had_error++ ? */
313 }
314 switch (type) {
315 case T_PTR:
316 if (strcasecmp(tname, bp) != 0) {
317 syslog(LOG_NOTICE|LOG_AUTH,
318 AskedForGot, qname, bp);
319 cp += n;
320 continue; /* XXX - had_error++ ? */
321 }
322 n = dn_expand(answer->buf, eom, cp, bp, buflen);
323 if (n < 0) {
324 had_error++;
325 break;
326 }
327 #if MULTI_PTRS_ARE_ALIASES
328 cp += n;
329 if (!haveanswer)
330 host.h_name = bp;
331 else if (ap < &host_aliases[MAXALIASES-1])
332 *ap++ = bp;
333 else
334 n = -1;
335 if (n != -1) {
336 n = strlen(bp) + 1; /* for the \0 */
337 bp += n;
338 buflen -= n;
339 }
340 break;
341 #else
342 host.h_name = bp;
343 h_errno = NETDB_SUCCESS;
344 return (&host);
345 #endif
346 case T_A:
347 if (strcasecmp(host.h_name, bp) != 0) {
348 syslog(LOG_NOTICE|LOG_AUTH,
349 AskedForGot, host.h_name, bp);
350 cp += n;
351 continue; /* XXX - had_error++ ? */
352 }
353 if (haveanswer) {
354 if (n != host.h_length) {
355 cp += n;
356 continue;
357 }
358 } else {
359 register int nn;
360
361 host.h_length = n;
362 host.h_addrtype = (class == C_IN)
363 ? AF_INET
364 : AF_UNSPEC;
365 host.h_name = bp;
366 nn = strlen(bp) + 1; /* for the \0 */
367 bp += nn;
368 buflen -= nn;
369 }
370
371 bp += sizeof(align) - ((u_long)bp % sizeof(align));
372
373 if (bp + n >= &hostbuf[MAXHOSTBUF]) {
374 dprintf("size (%d) too big\n", n);
375 had_error++;
376 continue;
377 }
378 if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
379 if (!toobig++)
380 dprintf("Too many addresses (%d)\n",
381 MAXADDRS);
382 cp += n;
383 continue;
384 }
385 bcopy(cp, *hap++ = bp, n);
386 bp += n;
387 cp += n;
388 break;
389 default:
390 dprintf("Impossible condition (type=%d)\n", type);
391 h_errno = NO_RECOVERY;
392 return (NULL);
393 } /*switch*/
394 if (!had_error)
395 haveanswer++;
396 } /*while*/
397 if (haveanswer) {
398 *ap = NULL;
399 *hap = NULL;
400 # if defined(RESOLVSORT)
401 /*
402 * Note: we sort even if host can take only one address
403 * in its return structures - should give it the "best"
404 * address in that case, not some random one
405 */
406 if (_res.nsort && haveanswer > 1 &&
407 qclass == C_IN && qtype == T_A)
408 addrsort(h_addr_ptrs, haveanswer);
409 # endif /*RESOLVSORT*/
410 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
411 /* nothing */
412 #else
413 host.h_addr = h_addr_ptrs[0];
414 #endif /*BSD*/
415 if (!host.h_name) {
416 n = strlen(qname) + 1; /* for the \0 */
417 strcpy(bp, qname);
418 host.h_name = bp;
419 }
420 h_errno = NETDB_SUCCESS;
421 return (&host);
422 } else {
423 h_errno = TRY_AGAIN;
424 return (NULL);
425 }
426 }
427
428 struct hostent *
429 gethostbyname(name)
430 const char *name;
431 {
432 #if defined(AF_INET6) && defined(RES_TRY_INET6)
433 struct hostent *hp;
434
435 if (_res.options & RES_TRY_INET6) {
436 hp = gethostbyname2(name, AF_INET6);
437 if (hp)
438 return (hp);
439 }
440 #endif
441 return (gethostbyname2(name, AF_INET));
442 }
443
444 #ifdef NOTDEF
445 static struct hostent *
446 gethostbyname_ipv4(name)
447 const char *name;
448 {
449 querybuf buf;
450 register const char *cp;
451 int n;
452 #if !defined(__APPLE__)
453 extern struct hostent *_gethtbyname();
454 #endif /* !NeXT */
455
456 if (hostbuf == NULL)
457 {
458 hostbuf = malloc(MAXHOSTBUF);
459 if (hostbuf == NULL) {
460 h_errno = NETDB_INTERNAL;
461 return (NULL);
462 }
463 }
464
465 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
466 h_errno = NETDB_INTERNAL;
467 return (NULL);
468 }
469
470 /*
471 * if there aren't any dots, it could be a user-level alias.
472 * this is also done in res_query() since we are not the only
473 * function that looks up host names.
474 */
475 if (!strchr(name, '.') && (cp = __hostalias(name)))
476 name = cp;
477
478 /*
479 * disallow names consisting only of digits/dots, unless
480 * they end in a dot.
481 */
482 if (isdigit(name[0]))
483 for (cp = name;; ++cp) {
484 if (!*cp) {
485 if (*--cp == '.')
486 break;
487 /*
488 * All-numeric, no dot at the end.
489 * Fake up a hostent as if we'd actually
490 * done a lookup.
491 */
492 if (!inet_aton(name, &host_addr)) {
493 h_errno = HOST_NOT_FOUND;
494 return (NULL);
495 }
496 strncpy(hostbuf, name, MAXDNAME);
497 hostbuf[MAXDNAME] = '\0';
498 host.h_name = hostbuf;
499 host.h_aliases = host_aliases;
500 host_aliases[0] = NULL;
501 host.h_addrtype = AF_INET;
502 host.h_length = INT32SZ;
503 h_addr_ptrs[0] = (char *)&host_addr;
504 h_addr_ptrs[1] = NULL;
505 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
506 host.h_addr_list = h_addr_ptrs;
507 #else
508 host.h_addr = h_addr_ptrs[0];
509 #endif
510 h_errno = NETDB_SUCCESS;
511 return (&host);
512 }
513 if (!isdigit(*cp) && *cp != '.')
514 break;
515 }
516
517 if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
518 dprintf("res_search failed (%d)\n", n);
519 #if !defined(__APPLE__)
520 if (errno == ECONNREFUSED)
521 return (_gethtbyname(name));
522 #endif
523 return (NULL);
524 }
525 return (getanswer(&buf, n, name, C_IN, T_A));
526 }
527 #endif
528
529 struct hostent *
530 gethostbyaddr(vaddr, len, type)
531 const void *vaddr;
532 socklen_t len;
533 int type;
534 {
535 int n;
536 querybuf buf;
537 register struct hostent *hp;
538 const char* addr = (const char *)vaddr;
539 char qbuf[MAXDNAME+1];
540 #ifdef SUNSECURITY
541 register struct hostent *rhp;
542 char **haddr;
543 u_long old_options;
544 char hname2[MAXDNAME+1];
545 #endif /*SUNSECURITY*/
546 #if !defined(__APPLE__)
547 extern struct hostent *_gethtbyaddr();
548 #endif /* !NeXT */
549
550 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
551 h_errno = NETDB_INTERNAL;
552 return (NULL);
553 }
554 if (type != AF_INET) {
555 errno = EAFNOSUPPORT;
556 h_errno = NETDB_INTERNAL;
557 return (NULL);
558 }
559 (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
560 ((unsigned)addr[3] & 0xff),
561 ((unsigned)addr[2] & 0xff),
562 ((unsigned)addr[1] & 0xff),
563 ((unsigned)addr[0] & 0xff));
564 n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
565 if (n < 0) {
566 dprintf("res_query failed (%d)\n", n);
567 #if !defined(__APPLE__)
568 if (errno == ECONNREFUSED)
569 return (_gethtbyaddr(addr, len, type));
570 #endif
571 return (NULL);
572 }
573 if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR)))
574 return (NULL); /* h_errno was set by getanswer() */
575 #ifdef SUNSECURITY
576 /*
577 * turn off search as the name should be absolute,
578 * 'localhost' should be matched by defnames
579 */
580 strncpy(hname2, hp->h_name, MAXDNAME);
581 hname2[MAXDNAME] = '\0';
582 old_options = _res.options;
583 _res.options &= ~RES_DNSRCH;
584 _res.options |= RES_DEFNAMES;
585 if (!(rhp = gethostbyname(hname2))) {
586 syslog(LOG_NOTICE|LOG_AUTH,
587 "gethostbyaddr: No A record for %s (verifying [%s])",
588 hname2, inet_ntoa(*((struct in_addr *)addr)));
589 _res.options = old_options;
590 h_errno = HOST_NOT_FOUND;
591 return (NULL);
592 }
593 _res.options = old_options;
594 for (haddr = rhp->h_addr_list; *haddr; haddr++)
595 if (!memcmp(*haddr, addr, INADDRSZ))
596 break;
597 if (!*haddr) {
598 syslog(LOG_NOTICE|LOG_AUTH,
599 "gethostbyaddr: A record of %s != PTR record [%s]",
600 hname2, inet_ntoa(*((struct in_addr *)addr)));
601 h_errno = HOST_NOT_FOUND;
602 return (NULL);
603 }
604 #endif /*SUNSECURITY*/
605 hp->h_addrtype = type;
606 hp->h_length = len;
607 h_addr_ptrs[0] = (char *)&host_addr;
608 h_addr_ptrs[1] = NULL;
609 host_addr = *(struct in_addr *)addr;
610 h_errno = NETDB_SUCCESS;
611 return (hp);
612 }
613
614 void
615 _sethtent(f)
616 int f;
617 {
618 if (!hostf)
619 hostf = fopen(_PATH_HOSTS, "r" );
620 else
621 rewind(hostf);
622 stayopen = f;
623 }
624
625 void
626 _endhtent()
627 {
628 if (hostf && !stayopen) {
629 (void) fclose(hostf);
630 hostf = NULL;
631 }
632 }
633
634 struct hostent *
635 _gethtent()
636 {
637 char *p;
638 register char *cp, **q;
639
640 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
641 h_errno = NETDB_INTERNAL;
642 return (NULL);
643 }
644 if (hostbuf == NULL) {
645 hostbuf = malloc(MAXHOSTBUF);
646 if (hostbuf == NULL) {
647 h_errno = NETDB_INTERNAL;
648 return (NULL);
649 }
650 }
651 again:
652 if (!(p = fgets(hostbuf, MAXHOSTBUF, hostf))) {
653 h_errno = HOST_NOT_FOUND;
654 return (NULL);
655 }
656 if (*p == '#')
657 goto again;
658 if (!(cp = strpbrk(p, "#\n")))
659 goto again;
660 *cp = '\0';
661 if (!(cp = strpbrk(p, " \t")))
662 goto again;
663 *cp++ = '\0';
664 /* THIS STUFF IS INTERNET SPECIFIC */
665 if (!inet_aton(p, &host_addr))
666 goto again;
667 h_addr_ptrs[0] = (char *)&host_addr;
668 h_addr_ptrs[1] = NULL;
669 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
670 host.h_addr_list = h_addr_ptrs;
671 #else
672 host.h_addr = h_addr_ptrs[0];
673 #endif
674 host.h_length = INT32SZ;
675 host.h_addrtype = AF_INET;
676 while (*cp == ' ' || *cp == '\t')
677 cp++;
678 host.h_name = cp;
679 q = host.h_aliases = host_aliases;
680 if ((cp = strpbrk(cp, " \t")))
681 *cp++ = '\0';
682 while (cp && *cp) {
683 if (*cp == ' ' || *cp == '\t') {
684 cp++;
685 continue;
686 }
687 if (q < &host_aliases[MAXALIASES - 1])
688 *q++ = cp;
689 if ((cp = strpbrk(cp, " \t")))
690 *cp++ = '\0';
691 }
692 *q = NULL;
693 h_errno = NETDB_SUCCESS;
694 return (&host);
695 }
696
697 struct hostent *
698 _gethtbyname(name)
699 char *name;
700 {
701 register struct hostent *p;
702 register char **cp;
703
704 _sethtent(0);
705 while ((p = _gethtent())) {
706 if (strcasecmp(p->h_name, name) == 0)
707 break;
708 for (cp = p->h_aliases; *cp != 0; cp++)
709 if (strcasecmp(*cp, name) == 0)
710 goto found;
711 }
712 found:
713 _endhtent();
714 return (p);
715 }
716
717 struct hostent *
718 _gethtbyaddr(addr, len, type)
719 const char *addr;
720 int len, type;
721 {
722 register struct hostent *p;
723
724 _sethtent(0);
725 while ((p = _gethtent()))
726 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
727 break;
728 _endhtent();
729 return (p);
730 }
731
732 #ifdef RESOLVSORT
733 static void
734 addrsort(ap, num)
735 char **ap;
736 int num;
737 {
738 int i, j;
739 char **p;
740 short aval[MAXADDRS];
741 int needsort = 0;
742
743 p = ap;
744 for (i = 0; i < num; i++, p++) {
745 for (j = 0 ; (unsigned)j < _res.nsort; j++)
746 if (_res.sort_list[j].addr.s_addr ==
747 (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
748 break;
749 aval[i] = j;
750 if (needsort == 0 && i > 0 && j < aval[i-1])
751 needsort = i;
752 }
753 if (!needsort)
754 return;
755
756 while (needsort < num) {
757 for (j = needsort - 1; j >= 0; j--) {
758 if (aval[j] > aval[j+1]) {
759 char *hp;
760
761 i = aval[j];
762 aval[j] = aval[j+1];
763 aval[j+1] = i;
764
765 hp = ap[j];
766 ap[j] = ap[j+1];
767 ap[j+1] = hp;
768
769 } else
770 break;
771 }
772 needsort++;
773 }
774 }
775 #endif
776
777 #if defined(BSD43_BSD43_NFS) || defined(sun)
778 /* some libc's out there are bound internally to these names (UMIPS) */
779 void
780 ht_sethostent(stayopen)
781 int stayopen;
782 {
783 _sethtent(stayopen);
784 }
785
786 void
787 ht_endhostent()
788 {
789 _endhtent();
790 }
791
792 struct hostent *
793 ht_gethostbyname(name)
794 char *name;
795 {
796 return (_gethtbyname(name));
797 }
798
799 struct hostent *
800 ht_gethostbyaddr(addr, len, type)
801 const char *addr;
802 int len, type;
803 {
804 return (_gethtbyaddr(addr, len, type));
805 }
806
807 struct hostent *
808 gethostent()
809 {
810 return (_gethtent());
811 }
812
813 void
814 dns_service()
815 {
816 return;
817 }
818
819 #undef dn_skipname
820 dn_skipname(comp_dn, eom)
821 const u_char *comp_dn, *eom;
822 {
823 return (__dn_skipname(comp_dn, eom));
824 }
825 #endif /*old-style libc with yp junk in it*/