Libinfo-129.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.6 2002/06/13 01:04:37 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/nameser.h>
89
90 #include <stdio.h>
91 #include <stdlib.h>
92 #include <netdb.h>
93 #include <resolv.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 struct hostent *
446 gethostbyname2(name, af)
447 const char *name;
448 int af;
449 {
450 if (_lu_running())
451 {
452 return getipnodebyname(name, af, 0, &h_errno);
453 }
454 else
455 {
456 if (af == AF_INET) return gethostbyname_ipv4(name);
457
458 errno = EAFNOSUPPORT;
459 h_errno = NETDB_INTERNAL;
460 return NULL;
461 }
462 }
463
464 static struct hostent *
465 gethostbyname_ipv4(name)
466 const char *name;
467 {
468 querybuf buf;
469 register const char *cp;
470 int n;
471 #if !defined(__APPLE__)
472 extern struct hostent *_gethtbyname();
473 #endif /* !NeXT */
474
475 if (hostbuf == NULL)
476 {
477 hostbuf = malloc(MAXHOSTBUF);
478 if (hostbuf == NULL) {
479 h_errno = NETDB_INTERNAL;
480 return (NULL);
481 }
482 }
483
484 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
485 h_errno = NETDB_INTERNAL;
486 return (NULL);
487 }
488
489 /*
490 * if there aren't any dots, it could be a user-level alias.
491 * this is also done in res_query() since we are not the only
492 * function that looks up host names.
493 */
494 if (!strchr(name, '.') && (cp = __hostalias(name)))
495 name = cp;
496
497 /*
498 * disallow names consisting only of digits/dots, unless
499 * they end in a dot.
500 */
501 if (isdigit(name[0]))
502 for (cp = name;; ++cp) {
503 if (!*cp) {
504 if (*--cp == '.')
505 break;
506 /*
507 * All-numeric, no dot at the end.
508 * Fake up a hostent as if we'd actually
509 * done a lookup.
510 */
511 if (!inet_aton(name, &host_addr)) {
512 h_errno = HOST_NOT_FOUND;
513 return (NULL);
514 }
515 strncpy(hostbuf, name, MAXDNAME);
516 hostbuf[MAXDNAME] = '\0';
517 host.h_name = hostbuf;
518 host.h_aliases = host_aliases;
519 host_aliases[0] = NULL;
520 host.h_addrtype = AF_INET;
521 host.h_length = INT32SZ;
522 h_addr_ptrs[0] = (char *)&host_addr;
523 h_addr_ptrs[1] = NULL;
524 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
525 host.h_addr_list = h_addr_ptrs;
526 #else
527 host.h_addr = h_addr_ptrs[0];
528 #endif
529 h_errno = NETDB_SUCCESS;
530 return (&host);
531 }
532 if (!isdigit(*cp) && *cp != '.')
533 break;
534 }
535
536 if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) {
537 dprintf("res_search failed (%d)\n", n);
538 #if !defined(__APPLE__)
539 if (errno == ECONNREFUSED)
540 return (_gethtbyname(name));
541 #endif
542 return (NULL);
543 }
544 return (getanswer(&buf, n, name, C_IN, T_A));
545 }
546
547 struct hostent *
548 gethostbyaddr(addr, len, type)
549 const char *addr;
550 int len, type;
551 {
552 int n;
553 querybuf buf;
554 register struct hostent *hp;
555 char qbuf[MAXDNAME+1];
556 #ifdef SUNSECURITY
557 register struct hostent *rhp;
558 char **haddr;
559 u_long old_options;
560 char hname2[MAXDNAME+1];
561 #endif /*SUNSECURITY*/
562 #if !defined(__APPLE__)
563 extern struct hostent *_gethtbyaddr();
564 #endif /* !NeXT */
565
566 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
567 h_errno = NETDB_INTERNAL;
568 return (NULL);
569 }
570 if (type != AF_INET) {
571 errno = EAFNOSUPPORT;
572 h_errno = NETDB_INTERNAL;
573 return (NULL);
574 }
575 (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
576 ((unsigned)addr[3] & 0xff),
577 ((unsigned)addr[2] & 0xff),
578 ((unsigned)addr[1] & 0xff),
579 ((unsigned)addr[0] & 0xff));
580 n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
581 if (n < 0) {
582 dprintf("res_query failed (%d)\n", n);
583 #if !defined(__APPLE__)
584 if (errno == ECONNREFUSED)
585 return (_gethtbyaddr(addr, len, type));
586 #endif
587 return (NULL);
588 }
589 if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR)))
590 return (NULL); /* h_errno was set by getanswer() */
591 #ifdef SUNSECURITY
592 /*
593 * turn off search as the name should be absolute,
594 * 'localhost' should be matched by defnames
595 */
596 strncpy(hname2, hp->h_name, MAXDNAME);
597 hname2[MAXDNAME] = '\0';
598 old_options = _res.options;
599 _res.options &= ~RES_DNSRCH;
600 _res.options |= RES_DEFNAMES;
601 if (!(rhp = gethostbyname(hname2))) {
602 syslog(LOG_NOTICE|LOG_AUTH,
603 "gethostbyaddr: No A record for %s (verifying [%s])",
604 hname2, inet_ntoa(*((struct in_addr *)addr)));
605 _res.options = old_options;
606 h_errno = HOST_NOT_FOUND;
607 return (NULL);
608 }
609 _res.options = old_options;
610 for (haddr = rhp->h_addr_list; *haddr; haddr++)
611 if (!memcmp(*haddr, addr, INADDRSZ))
612 break;
613 if (!*haddr) {
614 syslog(LOG_NOTICE|LOG_AUTH,
615 "gethostbyaddr: A record of %s != PTR record [%s]",
616 hname2, inet_ntoa(*((struct in_addr *)addr)));
617 h_errno = HOST_NOT_FOUND;
618 return (NULL);
619 }
620 #endif /*SUNSECURITY*/
621 hp->h_addrtype = type;
622 hp->h_length = len;
623 h_addr_ptrs[0] = (char *)&host_addr;
624 h_addr_ptrs[1] = NULL;
625 host_addr = *(struct in_addr *)addr;
626 h_errno = NETDB_SUCCESS;
627 return (hp);
628 }
629
630 void
631 _sethtent(f)
632 int f;
633 {
634 if (!hostf)
635 hostf = fopen(_PATH_HOSTS, "r" );
636 else
637 rewind(hostf);
638 stayopen = f;
639 }
640
641 void
642 _endhtent()
643 {
644 if (hostf && !stayopen) {
645 (void) fclose(hostf);
646 hostf = NULL;
647 }
648 }
649
650 struct hostent *
651 _gethtent()
652 {
653 char *p;
654 register char *cp, **q;
655
656 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
657 h_errno = NETDB_INTERNAL;
658 return (NULL);
659 }
660 if (hostbuf == NULL) {
661 hostbuf = malloc(MAXHOSTBUF);
662 if (hostbuf == NULL) {
663 h_errno = NETDB_INTERNAL;
664 return (NULL);
665 }
666 }
667 again:
668 if (!(p = fgets(hostbuf, MAXHOSTBUF, hostf))) {
669 h_errno = HOST_NOT_FOUND;
670 return (NULL);
671 }
672 if (*p == '#')
673 goto again;
674 if (!(cp = strpbrk(p, "#\n")))
675 goto again;
676 *cp = '\0';
677 if (!(cp = strpbrk(p, " \t")))
678 goto again;
679 *cp++ = '\0';
680 /* THIS STUFF IS INTERNET SPECIFIC */
681 if (!inet_aton(p, &host_addr))
682 goto again;
683 h_addr_ptrs[0] = (char *)&host_addr;
684 h_addr_ptrs[1] = NULL;
685 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
686 host.h_addr_list = h_addr_ptrs;
687 #else
688 host.h_addr = h_addr_ptrs[0];
689 #endif
690 host.h_length = INT32SZ;
691 host.h_addrtype = AF_INET;
692 while (*cp == ' ' || *cp == '\t')
693 cp++;
694 host.h_name = cp;
695 q = host.h_aliases = host_aliases;
696 if ((cp = strpbrk(cp, " \t")))
697 *cp++ = '\0';
698 while (cp && *cp) {
699 if (*cp == ' ' || *cp == '\t') {
700 cp++;
701 continue;
702 }
703 if (q < &host_aliases[MAXALIASES - 1])
704 *q++ = cp;
705 if ((cp = strpbrk(cp, " \t")))
706 *cp++ = '\0';
707 }
708 *q = NULL;
709 h_errno = NETDB_SUCCESS;
710 return (&host);
711 }
712
713 struct hostent *
714 _gethtbyname(name)
715 char *name;
716 {
717 register struct hostent *p;
718 register char **cp;
719
720 _sethtent(0);
721 while ((p = _gethtent())) {
722 if (strcasecmp(p->h_name, name) == 0)
723 break;
724 for (cp = p->h_aliases; *cp != 0; cp++)
725 if (strcasecmp(*cp, name) == 0)
726 goto found;
727 }
728 found:
729 _endhtent();
730 return (p);
731 }
732
733 struct hostent *
734 _gethtbyaddr(addr, len, type)
735 const char *addr;
736 int len, type;
737 {
738 register struct hostent *p;
739
740 _sethtent(0);
741 while ((p = _gethtent()))
742 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
743 break;
744 _endhtent();
745 return (p);
746 }
747
748 #ifdef RESOLVSORT
749 static void
750 addrsort(ap, num)
751 char **ap;
752 int num;
753 {
754 int i, j;
755 char **p;
756 short aval[MAXADDRS];
757 int needsort = 0;
758
759 p = ap;
760 for (i = 0; i < num; i++, p++) {
761 for (j = 0 ; (unsigned)j < _res.nsort; j++)
762 if (_res.sort_list[j].addr.s_addr ==
763 (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
764 break;
765 aval[i] = j;
766 if (needsort == 0 && i > 0 && j < aval[i-1])
767 needsort = i;
768 }
769 if (!needsort)
770 return;
771
772 while (needsort < num) {
773 for (j = needsort - 1; j >= 0; j--) {
774 if (aval[j] > aval[j+1]) {
775 char *hp;
776
777 i = aval[j];
778 aval[j] = aval[j+1];
779 aval[j+1] = i;
780
781 hp = ap[j];
782 ap[j] = ap[j+1];
783 ap[j+1] = hp;
784
785 } else
786 break;
787 }
788 needsort++;
789 }
790 }
791 #endif
792
793 #if defined(BSD43_BSD43_NFS) || defined(sun)
794 /* some libc's out there are bound internally to these names (UMIPS) */
795 void
796 ht_sethostent(stayopen)
797 int stayopen;
798 {
799 _sethtent(stayopen);
800 }
801
802 void
803 ht_endhostent()
804 {
805 _endhtent();
806 }
807
808 struct hostent *
809 ht_gethostbyname(name)
810 char *name;
811 {
812 return (_gethtbyname(name));
813 }
814
815 struct hostent *
816 ht_gethostbyaddr(addr, len, type)
817 const char *addr;
818 int len, type;
819 {
820 return (_gethtbyaddr(addr, len, type));
821 }
822
823 struct hostent *
824 gethostent()
825 {
826 return (_gethtent());
827 }
828
829 void
830 dns_service()
831 {
832 return;
833 }
834
835 #undef dn_skipname
836 dn_skipname(comp_dn, eom)
837 const u_char *comp_dn, *eom;
838 {
839 return (__dn_skipname(comp_dn, eom));
840 }
841 #endif /*old-style libc with yp junk in it*/