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