gethostbynis.c revision 92889
1/*-
2 * Copyright (c) 1994, Garrett Wollman
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23 * SUCH DAMAGE.
24 */
25
26#if defined(LIBC_SCCS) && !defined(lint)
27static const char rcsid[] =
28  "$FreeBSD: head/lib/libc/net/gethostbynis.c 92889 2002-03-21 18:49:23Z obrien $";
29#endif /* LIBC_SCCS and not lint */
30
31#include <sys/param.h>
32#include <sys/socket.h>
33#include <netinet/in.h>
34#include <arpa/inet.h>
35#include <arpa/nameser.h>
36#include <netdb.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <ctype.h>
40#include <errno.h>
41#include <string.h>
42#include <stdarg.h>
43#include <nsswitch.h>
44#ifdef YP
45#include <rpc/rpc.h>
46#include <rpcsvc/yp_prot.h>
47#include <rpcsvc/ypclnt.h>
48#endif
49
50#define	MAXALIASES	35
51#define	MAXADDRS	35
52
53extern int h_errno;
54
55#ifdef YP
56static char *host_aliases[MAXALIASES];
57static char hostaddr[MAXADDRS];
58static char *host_addrs[2];
59
60static struct hostent *
61_gethostbynis(name, map, af)
62	const char *name;
63	char *map;
64	int af;
65{
66	char *cp, **q;
67	char *result;
68	int resultlen,size;
69	static struct hostent h;
70	static char *domain = (char *)NULL;
71	static char ypbuf[YPMAXRECORD + 2];
72
73	switch(af) {
74	case AF_INET:
75		size = NS_INADDRSZ;
76		break;
77	default:
78	case AF_INET6:
79		size = NS_IN6ADDRSZ;
80		errno = EAFNOSUPPORT;
81		h_errno = NETDB_INTERNAL;
82		return NULL;
83	}
84
85	if (domain == (char *)NULL)
86		if (yp_get_default_domain (&domain)) {
87			h_errno = NETDB_INTERNAL;
88			return ((struct hostent *)NULL);
89		}
90
91	if (yp_match(domain, map, name, strlen(name), &result, &resultlen)) {
92		h_errno = HOST_NOT_FOUND;
93		return ((struct hostent *)NULL);
94	}
95
96	/* avoid potential memory leak */
97	bcopy((char *)result, (char *)&ypbuf, resultlen);
98	ypbuf[resultlen] = '\0';
99	free(result);
100	result = (char *)&ypbuf;
101
102	if ((cp = index(result, '\n')))
103		*cp = '\0';
104
105	cp = strpbrk(result, " \t");
106	*cp++ = '\0';
107	h.h_addr_list = host_addrs;
108	h.h_addr = hostaddr;
109	*((u_long *)h.h_addr) = inet_addr(result);
110	h.h_length = size;
111	h.h_addrtype = AF_INET;
112	while (*cp == ' ' || *cp == '\t')
113		cp++;
114	h.h_name = cp;
115	q = h.h_aliases = host_aliases;
116	cp = strpbrk(cp, " \t");
117	if (cp != NULL)
118		*cp++ = '\0';
119	while (cp && *cp) {
120		if (*cp == ' ' || *cp == '\t') {
121			cp++;
122			continue;
123		}
124		if (q < &host_aliases[MAXALIASES - 1])
125			*q++ = cp;
126		cp = strpbrk(cp, " \t");
127		if (cp != NULL)
128			*cp++ = '\0';
129	}
130	*q = NULL;
131	return (&h);
132}
133#endif /* YP */
134
135/* XXX _gethostbynisname/_gethostbynisaddr only used by getaddrinfo */
136struct hostent *
137_gethostbynisname(const char *name, int af)
138{
139#ifdef YP
140	return _gethostbynis(name, "hosts.byname", af);
141#else
142	return NULL;
143#endif
144}
145
146struct hostent *
147_gethostbynisaddr(const char *addr, int len, int af)
148{
149#ifdef YP
150	return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),
151			     "hosts.byaddr", af);
152#else
153	return NULL;
154#endif
155}
156
157
158int
159_nis_gethostbyname(void *rval, void *cb_data, va_list ap)
160{
161#ifdef YP
162	const char *name;
163	int af;
164
165	name = va_arg(ap, const char *);
166	af = va_arg(ap, int);
167
168	*(struct hostent **)rval = _gethostbynis(name, "hosts.byname", af);
169	return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
170#else
171	return NS_UNAVAIL;
172#endif
173}
174
175int
176_nis_gethostbyaddr(void *rval, void *cb_data, va_list ap)
177{
178#ifdef YP
179	const char *addr;
180	int len;
181	int af;
182
183	addr = va_arg(ap, const char *);
184	len = va_arg(ap, int);
185	af = va_arg(ap, int);
186
187	*(struct hostent **)rval =_gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af);
188	return (*(struct hostent **)rval != NULL) ? NS_SUCCESS : NS_NOTFOUND;
189#else
190	return NS_UNAVAIL;
191#endif
192}
193