Libinfo-173.1.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.8 2003/07/03 21:56:17 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 static struct hostent *gethostbyname_ipv4 __P((const char *));
122
123 static struct hostent host;
124 static char *host_aliases[MAXALIASES];
125 static char *hostbuf = NULL;
126 static struct in_addr host_addr;
127 static FILE *hostf = NULL;
128 static int stayopen = 0;
129
130 #ifdef RESOLVSORT
131 static void addrsort __P((char **, int));
132 #endif
133
134 #if PACKETSZ > 1024
135 #define MAXPACKET PACKETSZ
136 #else
137 #define MAXPACKET 1024
138 #endif
139
140 typedef union {
141 HEADER hdr;
142 u_char buf[MAXPACKET];
143 } querybuf;
144
145 typedef union {
146 int32_t al;
147 char ac;
148 } align;
149
150 extern int h_errno;
151
152 extern int _lu_running(void);
153
154 #ifdef DEBUG
155 static void
156 dprintf(msg, num)
157 char *msg;
158 int num;
159 {
160 if (_res.options & RES_DEBUG) {
161 int save = errno;
162
163 printf(msg, num);
164 errno = save;
165 }
166 }
167 #else
168 # define dprintf(msg, num) /*nada*/
169 #endif
170
171 static struct hostent *
172 getanswer(answer, anslen, qname, qclass, qtype)
173 const querybuf *answer;
174 int anslen;
175 const char *qname;
176 int qclass, qtype;
177 {
178 register const HEADER *hp;
179 register const u_char *cp;
180 register int n;
181 const u_char *eom;
182 char *bp, **ap, **hap;
183 int type, class, buflen, ancount, qdcount;
184 int haveanswer, had_error;
185 int toobig = 0;
186 char tbuf[MAXDNAME+1];
187 const char *tname;
188
189 if (hostbuf == NULL) {
190 hostbuf = malloc(MAXHOSTBUF);
191 if (hostbuf == NULL)
192 return (NULL);
193 }
194 buflen = MAXHOSTBUF;
195
196 tname = qname;
197 host.h_name = NULL;
198 eom = answer->buf + anslen;
199 /*
200 * find first satisfactory answer
201 */
202 hp = &answer->hdr;
203 ancount = ntohs(hp->ancount);
204 qdcount = ntohs(hp->qdcount);
205 bp = hostbuf;
206 cp = answer->buf + HFIXEDSZ;
207 if (qdcount != 1) {
208 h_errno = NO_RECOVERY;
209 return (NULL);
210 }
211 if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) {
212 h_errno = NO_RECOVERY;
213 return (NULL);
214 }
215 cp += n + QFIXEDSZ;
216 if (qtype == T_A) {
217 /* res_send() has already verified that the query name is the
218 * same as the one we sent; this just gets the expanded name
219 * (i.e., with the succeeding search-domain tacked on).
220 */
221 n = strlen(bp) + 1; /* for the \0 */
222 host.h_name = bp;
223 bp += n;
224 buflen -= n;
225 /* The qname can be abbreviated, but h_name is now absolute. */
226 qname = host.h_name;
227 }
228 ap = host_aliases;
229 *ap = NULL;
230 host.h_aliases = host_aliases;
231 hap = h_addr_ptrs;
232 *hap = NULL;
233 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
234 host.h_addr_list = h_addr_ptrs;
235 #endif
236 haveanswer = 0;
237 had_error = 0;
238 while (ancount-- > 0 && cp < eom && !had_error) {
239 n = dn_expand(answer->buf, eom, cp, bp, buflen);
240 if (n < 0) {
241 had_error++;
242 continue;
243 }
244 cp += n; /* name */
245 type = _getshort(cp);
246 cp += INT16SZ; /* type */
247 class = _getshort(cp);
248 cp += INT16SZ + INT32SZ; /* class, TTL */
249 n = _getshort(cp);
250 cp += INT16SZ; /* len */
251 if (class != qclass) {
252 /* XXX - debug? syslog? */
253 cp += n;
254 continue; /* XXX - had_error++ ? */
255 }
256 if (qtype == T_A && type == T_CNAME) {
257 if (ap >= &host_aliases[MAXALIASES-1])
258 continue;
259 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
260 if (n < 0) {
261 had_error++;
262 continue;
263 }
264 cp += n;
265 if (host.h_name && strcasecmp(host.h_name, bp) != 0) {
266 syslog(LOG_NOTICE|LOG_AUTH,
267 "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"",
268 host.h_name, bp);
269 continue; /* XXX - had_error++ ? */
270 }
271 /* Store alias. */
272 *ap++ = bp;
273 n = strlen(bp) + 1; /* for the \0 */
274 bp += n;
275 buflen -= n;
276 /* Get canonical name. */
277 n = strlen(tbuf) + 1; /* for the \0 */
278 if (n > buflen) {
279 had_error++;
280 continue;
281 }
282 strcpy(bp, tbuf);
283 host.h_name = bp;
284 bp += n;
285 buflen -= n;
286 continue;
287 }
288 if (qtype == T_PTR && type == T_CNAME) {
289 n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
290 if (n < 0) {
291 had_error++;
292 continue;
293 }
294 cp += n;
295 /* Get canonical name. */
296 n = strlen(tbuf) + 1; /* for the \0 */
297 if (n > buflen) {
298 had_error++;
299 continue;
300 }
301 strcpy(bp, tbuf);
302 tname = bp;
303 bp += n;
304 buflen -= n;
305 continue;
306 }
307 if (type != qtype) {
308 syslog(LOG_NOTICE|LOG_AUTH,
309 "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"",
310 qname, p_class(qclass), p_type(qtype),
311 p_type(type));
312 cp += n;
313 continue; /* XXX - had_error++ ? */
314 }
315 switch (type) {
316 case T_PTR:
317 if (strcasecmp(tname, bp) != 0) {
318 syslog(LOG_NOTICE|LOG_AUTH,
319 AskedForGot, qname, bp);
320 cp += n;
321 continue; /* XXX - had_error++ ? */
322 }
323 n = dn_expand(answer->buf, eom, cp, bp, buflen);
324 if (n < 0) {
325 had_error++;
326 break;
327 }
328 #if MULTI_PTRS_ARE_ALIASES
329 cp += n;
330 if (!haveanswer)
331 host.h_name = bp;
332 else if (ap < &host_aliases[MAXALIASES-1])
333 *ap++ = bp;
334 else
335 n = -1;
336 if (n != -1) {
337 n = strlen(bp) + 1; /* for the \0 */
338 bp += n;
339 buflen -= n;
340 }
341 break;
342 #else
343 host.h_name = bp;
344 h_errno = NETDB_SUCCESS;
345 return (&host);
346 #endif
347 case T_A:
348 if (strcasecmp(host.h_name, bp) != 0) {
349 syslog(LOG_NOTICE|LOG_AUTH,
350 AskedForGot, host.h_name, bp);
351 cp += n;
352 continue; /* XXX - had_error++ ? */
353 }
354 if (haveanswer) {
355 if (n != host.h_length) {
356 cp += n;
357 continue;
358 }
359 } else {
360 register int nn;
361
362 host.h_length = n;
363 host.h_addrtype = (class == C_IN)
364 ? AF_INET
365 : AF_UNSPEC;
366 host.h_name = bp;
367 nn = strlen(bp) + 1; /* for the \0 */
368 bp += nn;
369 buflen -= nn;
370 }
371
372 bp += sizeof(align) - ((u_long)bp % sizeof(align));
373
374 if (bp + n >= &hostbuf[MAXHOSTBUF]) {
375 dprintf("size (%d) too big\n", n);
376 had_error++;
377 continue;
378 }
379 if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
380 if (!toobig++)
381 dprintf("Too many addresses (%d)\n",
382 MAXADDRS);
383 cp += n;
384 continue;
385 }
386 bcopy(cp, *hap++ = bp, n);
387 bp += n;
388 cp += n;
389 break;
390 default:
391 dprintf("Impossible condition (type=%d)\n", type);
392 h_errno = NO_RECOVERY;
393 return (NULL);
394 } /*switch*/
395 if (!had_error)
396 haveanswer++;
397 } /*while*/
398 if (haveanswer) {
399 *ap = NULL;
400 *hap = NULL;
401 # if defined(RESOLVSORT)
402 /*
403 * Note: we sort even if host can take only one address
404 * in its return structures - should give it the "best"
405 * address in that case, not some random one
406 */
407 if (_res.nsort && haveanswer > 1 &&
408 qclass == C_IN && qtype == T_A)
409 addrsort(h_addr_ptrs, haveanswer);
410 # endif /*RESOLVSORT*/
411 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
412 /* nothing */
413 #else
414 host.h_addr = h_addr_ptrs[0];
415 #endif /*BSD*/
416 if (!host.h_name) {
417 n = strlen(qname) + 1; /* for the \0 */
418 strcpy(bp, qname);
419 host.h_name = bp;
420 }
421 h_errno = NETDB_SUCCESS;
422 return (&host);
423 } else {
424 h_errno = TRY_AGAIN;
425 return (NULL);
426 }
427 }
428
429 struct hostent *
430 gethostbyname(name)
431 const char *name;
432 {
433 #if defined(AF_INET6) && defined(RES_TRY_INET6)
434 struct hostent *hp;
435
436 if (_res.options & RES_TRY_INET6) {
437 hp = gethostbyname2(name, AF_INET6);
438 if (hp)
439 return (hp);
440 }
441 #endif
442 return (gethostbyname2(name, AF_INET));
443 }
444
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
528 struct hostent *
529 gethostbyaddr(addr, len, type)
530 const char *addr;
531 int len, type;
532 {
533 int n;
534 querybuf buf;
535 register struct hostent *hp;
536 char qbuf[MAXDNAME+1];
537 #ifdef SUNSECURITY
538 register struct hostent *rhp;
539 char **haddr;
540 u_long old_options;
541 char hname2[MAXDNAME+1];
542 #endif /*SUNSECURITY*/
543 #if !defined(__APPLE__)
544 extern struct hostent *_gethtbyaddr();
545 #endif /* !NeXT */
546
547 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
548 h_errno = NETDB_INTERNAL;
549 return (NULL);
550 }
551 if (type != AF_INET) {
552 errno = EAFNOSUPPORT;
553 h_errno = NETDB_INTERNAL;
554 return (NULL);
555 }
556 (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
557 ((unsigned)addr[3] & 0xff),
558 ((unsigned)addr[2] & 0xff),
559 ((unsigned)addr[1] & 0xff),
560 ((unsigned)addr[0] & 0xff));
561 n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
562 if (n < 0) {
563 dprintf("res_query failed (%d)\n", n);
564 #if !defined(__APPLE__)
565 if (errno == ECONNREFUSED)
566 return (_gethtbyaddr(addr, len, type));
567 #endif
568 return (NULL);
569 }
570 if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR)))
571 return (NULL); /* h_errno was set by getanswer() */
572 #ifdef SUNSECURITY
573 /*
574 * turn off search as the name should be absolute,
575 * 'localhost' should be matched by defnames
576 */
577 strncpy(hname2, hp->h_name, MAXDNAME);
578 hname2[MAXDNAME] = '\0';
579 old_options = _res.options;
580 _res.options &= ~RES_DNSRCH;
581 _res.options |= RES_DEFNAMES;
582 if (!(rhp = gethostbyname(hname2))) {
583 syslog(LOG_NOTICE|LOG_AUTH,
584 "gethostbyaddr: No A record for %s (verifying [%s])",
585 hname2, inet_ntoa(*((struct in_addr *)addr)));
586 _res.options = old_options;
587 h_errno = HOST_NOT_FOUND;
588 return (NULL);
589 }
590 _res.options = old_options;
591 for (haddr = rhp->h_addr_list; *haddr; haddr++)
592 if (!memcmp(*haddr, addr, INADDRSZ))
593 break;
594 if (!*haddr) {
595 syslog(LOG_NOTICE|LOG_AUTH,
596 "gethostbyaddr: A record of %s != PTR record [%s]",
597 hname2, inet_ntoa(*((struct in_addr *)addr)));
598 h_errno = HOST_NOT_FOUND;
599 return (NULL);
600 }
601 #endif /*SUNSECURITY*/
602 hp->h_addrtype = type;
603 hp->h_length = len;
604 h_addr_ptrs[0] = (char *)&host_addr;
605 h_addr_ptrs[1] = NULL;
606 host_addr = *(struct in_addr *)addr;
607 h_errno = NETDB_SUCCESS;
608 return (hp);
609 }
610
611 void
612 _sethtent(f)
613 int f;
614 {
615 if (!hostf)
616 hostf = fopen(_PATH_HOSTS, "r" );
617 else
618 rewind(hostf);
619 stayopen = f;
620 }
621
622 void
623 _endhtent()
624 {
625 if (hostf && !stayopen) {
626 (void) fclose(hostf);
627 hostf = NULL;
628 }
629 }
630
631 struct hostent *
632 _gethtent()
633 {
634 char *p;
635 register char *cp, **q;
636
637 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
638 h_errno = NETDB_INTERNAL;
639 return (NULL);
640 }
641 if (hostbuf == NULL) {
642 hostbuf = malloc(MAXHOSTBUF);
643 if (hostbuf == NULL) {
644 h_errno = NETDB_INTERNAL;
645 return (NULL);
646 }
647 }
648 again:
649 if (!(p = fgets(hostbuf, MAXHOSTBUF, hostf))) {
650 h_errno = HOST_NOT_FOUND;
651 return (NULL);
652 }
653 if (*p == '#')
654 goto again;
655 if (!(cp = strpbrk(p, "#\n")))
656 goto again;
657 *cp = '\0';
658 if (!(cp = strpbrk(p, " \t")))
659 goto again;
660 *cp++ = '\0';
661 /* THIS STUFF IS INTERNET SPECIFIC */
662 if (!inet_aton(p, &host_addr))
663 goto again;
664 h_addr_ptrs[0] = (char *)&host_addr;
665 h_addr_ptrs[1] = NULL;
666 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
667 host.h_addr_list = h_addr_ptrs;
668 #else
669 host.h_addr = h_addr_ptrs[0];
670 #endif
671 host.h_length = INT32SZ;
672 host.h_addrtype = AF_INET;
673 while (*cp == ' ' || *cp == '\t')
674 cp++;
675 host.h_name = cp;
676 q = host.h_aliases = host_aliases;
677 if ((cp = strpbrk(cp, " \t")))
678 *cp++ = '\0';
679 while (cp && *cp) {
680 if (*cp == ' ' || *cp == '\t') {
681 cp++;
682 continue;
683 }
684 if (q < &host_aliases[MAXALIASES - 1])
685 *q++ = cp;
686 if ((cp = strpbrk(cp, " \t")))
687 *cp++ = '\0';
688 }
689 *q = NULL;
690 h_errno = NETDB_SUCCESS;
691 return (&host);
692 }
693
694 struct hostent *
695 _gethtbyname(name)
696 char *name;
697 {
698 register struct hostent *p;
699 register char **cp;
700
701 _sethtent(0);
702 while ((p = _gethtent())) {
703 if (strcasecmp(p->h_name, name) == 0)
704 break;
705 for (cp = p->h_aliases; *cp != 0; cp++)
706 if (strcasecmp(*cp, name) == 0)
707 goto found;
708 }
709 found:
710 _endhtent();
711 return (p);
712 }
713
714 struct hostent *
715 _gethtbyaddr(addr, len, type)
716 const char *addr;
717 int len, type;
718 {
719 register struct hostent *p;
720
721 _sethtent(0);
722 while ((p = _gethtent()))
723 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
724 break;
725 _endhtent();
726 return (p);
727 }
728
729 #ifdef RESOLVSORT
730 static void
731 addrsort(ap, num)
732 char **ap;
733 int num;
734 {
735 int i, j;
736 char **p;
737 short aval[MAXADDRS];
738 int needsort = 0;
739
740 p = ap;
741 for (i = 0; i < num; i++, p++) {
742 for (j = 0 ; (unsigned)j < _res.nsort; j++)
743 if (_res.sort_list[j].addr.s_addr ==
744 (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
745 break;
746 aval[i] = j;
747 if (needsort == 0 && i > 0 && j < aval[i-1])
748 needsort = i;
749 }
750 if (!needsort)
751 return;
752
753 while (needsort < num) {
754 for (j = needsort - 1; j >= 0; j--) {
755 if (aval[j] > aval[j+1]) {
756 char *hp;
757
758 i = aval[j];
759 aval[j] = aval[j+1];
760 aval[j+1] = i;
761
762 hp = ap[j];
763 ap[j] = ap[j+1];
764 ap[j+1] = hp;
765
766 } else
767 break;
768 }
769 needsort++;
770 }
771 }
772 #endif
773
774 #if defined(BSD43_BSD43_NFS) || defined(sun)
775 /* some libc's out there are bound internally to these names (UMIPS) */
776 void
777 ht_sethostent(stayopen)
778 int stayopen;
779 {
780 _sethtent(stayopen);
781 }
782
783 void
784 ht_endhostent()
785 {
786 _endhtent();
787 }
788
789 struct hostent *
790 ht_gethostbyname(name)
791 char *name;
792 {
793 return (_gethtbyname(name));
794 }
795
796 struct hostent *
797 ht_gethostbyaddr(addr, len, type)
798 const char *addr;
799 int len, type;
800 {
801 return (_gethtbyaddr(addr, len, type));
802 }
803
804 struct hostent *
805 gethostent()
806 {
807 return (_gethtent());
808 }
809
810 void
811 dns_service()
812 {
813 return;
814 }
815
816 #undef dn_skipname
817 dn_skipname(comp_dn, eom)
818 const u_char *comp_dn, *eom;
819 {
820 return (__dn_skipname(comp_dn, eom));
821 }
822 #endif /*old-style libc with yp junk in it*/