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