]> git.saurik.com Git - apple/libinfo.git/blob - dns.subproj/gethnamaddr.c
Libinfo-222.3.3.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 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(vaddr, len, type)
530 const void *vaddr;
531 socklen_t len;
532 int type;
533 {
534 int n;
535 querybuf buf;
536 register struct hostent *hp;
537 const char* addr = (const char *)vaddr;
538 char qbuf[MAXDNAME+1];
539 #ifdef SUNSECURITY
540 register struct hostent *rhp;
541 char **haddr;
542 u_long old_options;
543 char hname2[MAXDNAME+1];
544 #endif /*SUNSECURITY*/
545 #if !defined(__APPLE__)
546 extern struct hostent *_gethtbyaddr();
547 #endif /* !NeXT */
548
549 if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
550 h_errno = NETDB_INTERNAL;
551 return (NULL);
552 }
553 if (type != AF_INET) {
554 errno = EAFNOSUPPORT;
555 h_errno = NETDB_INTERNAL;
556 return (NULL);
557 }
558 (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
559 ((unsigned)addr[3] & 0xff),
560 ((unsigned)addr[2] & 0xff),
561 ((unsigned)addr[1] & 0xff),
562 ((unsigned)addr[0] & 0xff));
563 n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
564 if (n < 0) {
565 dprintf("res_query failed (%d)\n", n);
566 #if !defined(__APPLE__)
567 if (errno == ECONNREFUSED)
568 return (_gethtbyaddr(addr, len, type));
569 #endif
570 return (NULL);
571 }
572 if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR)))
573 return (NULL); /* h_errno was set by getanswer() */
574 #ifdef SUNSECURITY
575 /*
576 * turn off search as the name should be absolute,
577 * 'localhost' should be matched by defnames
578 */
579 strncpy(hname2, hp->h_name, MAXDNAME);
580 hname2[MAXDNAME] = '\0';
581 old_options = _res.options;
582 _res.options &= ~RES_DNSRCH;
583 _res.options |= RES_DEFNAMES;
584 if (!(rhp = gethostbyname(hname2))) {
585 syslog(LOG_NOTICE|LOG_AUTH,
586 "gethostbyaddr: No A record for %s (verifying [%s])",
587 hname2, inet_ntoa(*((struct in_addr *)addr)));
588 _res.options = old_options;
589 h_errno = HOST_NOT_FOUND;
590 return (NULL);
591 }
592 _res.options = old_options;
593 for (haddr = rhp->h_addr_list; *haddr; haddr++)
594 if (!memcmp(*haddr, addr, INADDRSZ))
595 break;
596 if (!*haddr) {
597 syslog(LOG_NOTICE|LOG_AUTH,
598 "gethostbyaddr: A record of %s != PTR record [%s]",
599 hname2, inet_ntoa(*((struct in_addr *)addr)));
600 h_errno = HOST_NOT_FOUND;
601 return (NULL);
602 }
603 #endif /*SUNSECURITY*/
604 hp->h_addrtype = type;
605 hp->h_length = len;
606 h_addr_ptrs[0] = (char *)&host_addr;
607 h_addr_ptrs[1] = NULL;
608 host_addr = *(struct in_addr *)addr;
609 h_errno = NETDB_SUCCESS;
610 return (hp);
611 }
612
613 void
614 _sethtent(f)
615 int f;
616 {
617 if (!hostf)
618 hostf = fopen(_PATH_HOSTS, "r" );
619 else
620 rewind(hostf);
621 stayopen = f;
622 }
623
624 void
625 _endhtent()
626 {
627 if (hostf && !stayopen) {
628 (void) fclose(hostf);
629 hostf = NULL;
630 }
631 }
632
633 struct hostent *
634 _gethtent()
635 {
636 char *p;
637 register char *cp, **q;
638
639 if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
640 h_errno = NETDB_INTERNAL;
641 return (NULL);
642 }
643 if (hostbuf == NULL) {
644 hostbuf = malloc(MAXHOSTBUF);
645 if (hostbuf == NULL) {
646 h_errno = NETDB_INTERNAL;
647 return (NULL);
648 }
649 }
650 again:
651 if (!(p = fgets(hostbuf, MAXHOSTBUF, hostf))) {
652 h_errno = HOST_NOT_FOUND;
653 return (NULL);
654 }
655 if (*p == '#')
656 goto again;
657 if (!(cp = strpbrk(p, "#\n")))
658 goto again;
659 *cp = '\0';
660 if (!(cp = strpbrk(p, " \t")))
661 goto again;
662 *cp++ = '\0';
663 /* THIS STUFF IS INTERNET SPECIFIC */
664 if (!inet_aton(p, &host_addr))
665 goto again;
666 h_addr_ptrs[0] = (char *)&host_addr;
667 h_addr_ptrs[1] = NULL;
668 #if BSD >= 43 || defined(h_addr) /* new-style hostent structure */
669 host.h_addr_list = h_addr_ptrs;
670 #else
671 host.h_addr = h_addr_ptrs[0];
672 #endif
673 host.h_length = INT32SZ;
674 host.h_addrtype = AF_INET;
675 while (*cp == ' ' || *cp == '\t')
676 cp++;
677 host.h_name = cp;
678 q = host.h_aliases = host_aliases;
679 if ((cp = strpbrk(cp, " \t")))
680 *cp++ = '\0';
681 while (cp && *cp) {
682 if (*cp == ' ' || *cp == '\t') {
683 cp++;
684 continue;
685 }
686 if (q < &host_aliases[MAXALIASES - 1])
687 *q++ = cp;
688 if ((cp = strpbrk(cp, " \t")))
689 *cp++ = '\0';
690 }
691 *q = NULL;
692 h_errno = NETDB_SUCCESS;
693 return (&host);
694 }
695
696 struct hostent *
697 _gethtbyname(name)
698 char *name;
699 {
700 register struct hostent *p;
701 register char **cp;
702
703 _sethtent(0);
704 while ((p = _gethtent())) {
705 if (strcasecmp(p->h_name, name) == 0)
706 break;
707 for (cp = p->h_aliases; *cp != 0; cp++)
708 if (strcasecmp(*cp, name) == 0)
709 goto found;
710 }
711 found:
712 _endhtent();
713 return (p);
714 }
715
716 struct hostent *
717 _gethtbyaddr(addr, len, type)
718 const char *addr;
719 int len, type;
720 {
721 register struct hostent *p;
722
723 _sethtent(0);
724 while ((p = _gethtent()))
725 if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len))
726 break;
727 _endhtent();
728 return (p);
729 }
730
731 #ifdef RESOLVSORT
732 static void
733 addrsort(ap, num)
734 char **ap;
735 int num;
736 {
737 int i, j;
738 char **p;
739 short aval[MAXADDRS];
740 int needsort = 0;
741
742 p = ap;
743 for (i = 0; i < num; i++, p++) {
744 for (j = 0 ; (unsigned)j < _res.nsort; j++)
745 if (_res.sort_list[j].addr.s_addr ==
746 (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
747 break;
748 aval[i] = j;
749 if (needsort == 0 && i > 0 && j < aval[i-1])
750 needsort = i;
751 }
752 if (!needsort)
753 return;
754
755 while (needsort < num) {
756 for (j = needsort - 1; j >= 0; j--) {
757 if (aval[j] > aval[j+1]) {
758 char *hp;
759
760 i = aval[j];
761 aval[j] = aval[j+1];
762 aval[j+1] = i;
763
764 hp = ap[j];
765 ap[j] = ap[j+1];
766 ap[j+1] = hp;
767
768 } else
769 break;
770 }
771 needsort++;
772 }
773 }
774 #endif
775
776 #if defined(BSD43_BSD43_NFS) || defined(sun)
777 /* some libc's out there are bound internally to these names (UMIPS) */
778 void
779 ht_sethostent(stayopen)
780 int stayopen;
781 {
782 _sethtent(stayopen);
783 }
784
785 void
786 ht_endhostent()
787 {
788 _endhtent();
789 }
790
791 struct hostent *
792 ht_gethostbyname(name)
793 char *name;
794 {
795 return (_gethtbyname(name));
796 }
797
798 struct hostent *
799 ht_gethostbyaddr(addr, len, type)
800 const char *addr;
801 int len, type;
802 {
803 return (_gethtbyaddr(addr, len, type));
804 }
805
806 struct hostent *
807 gethostent()
808 {
809 return (_gethtent());
810 }
811
812 void
813 dns_service()
814 {
815 return;
816 }
817
818 #undef dn_skipname
819 dn_skipname(comp_dn, eom)
820 const u_char *comp_dn, *eom;
821 {
822 return (__dn_skipname(comp_dn, eom));
823 }
824 #endif /*old-style libc with yp junk in it*/