gethostnamadr.c revision 17141
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 char sccsid[] = "@(#)$Id: gethostnamadr.c,v 1.7 1995/05/30 05:40:45 rgrimes Exp $";
28static char rcsid[] = "$Id: gethostnamadr.c,v 1.7 1995/05/30 05:40:45 rgrimes Exp $";
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 <netdb.h>
36#include <stdio.h>
37#include <ctype.h>
38#include <errno.h>
39#include <string.h>
40
41extern void _sethosthtent __P(( int ));
42extern void _endhosthtent __P(( void ));
43extern void _sethostdnsent __P(( int ));
44extern void _endhostdnsent __P(( void ));
45
46extern struct hostent * _gethostbyhtname  __P((const char *));
47extern struct hostent * _gethostbydnsname __P((const char *));
48extern struct hostent * _gethostbynisname __P((const char *));
49extern struct hostent * _gethostbyhtaddr  __P((const char *, int, int));
50extern struct hostent * _gethostbydnsaddr __P((const char *, int, int));
51extern struct hostent * _gethostbynisaddr __P((const char *, int, int));
52
53#define _PATH_HOSTCONF	"/etc/host.conf"
54
55enum service_type {
56  SERVICE_NONE = 0,
57  SERVICE_BIND,
58  SERVICE_HOSTS,
59  SERVICE_NIS };
60#define SERVICE_MAX	SERVICE_NIS
61
62static struct {
63  const char *name;
64  enum service_type type;
65} service_names[] = {
66  { "hosts", SERVICE_HOSTS },
67  { "/etc/hosts", SERVICE_HOSTS },
68  { "hosttable", SERVICE_HOSTS },
69  { "htable", SERVICE_HOSTS },
70  { "bind", SERVICE_BIND },
71  { "dns", SERVICE_BIND },
72  { "domain", SERVICE_BIND },
73  { "yp", SERVICE_NIS },
74  { "yellowpages", SERVICE_NIS },
75  { "nis", SERVICE_NIS },
76  { 0, SERVICE_NONE }
77};
78
79static enum service_type service_order[SERVICE_MAX + 1];
80static int service_done = 0;
81
82static enum service_type
83get_service_name(const char *name) {
84	int i;
85	for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
86		if(!strcasecmp(name, service_names[i].name)) {
87			return service_names[i].type;
88		}
89	}
90	return SERVICE_NONE;
91}
92
93static void
94init_services()
95{
96	char *cp, *p, buf[BUFSIZ];
97	register int cc = 0;
98	FILE *fd;
99
100	if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) {
101				/* make some assumptions */
102		service_order[0] = SERVICE_BIND;
103		service_order[1] = SERVICE_HOSTS;
104		service_order[2] = SERVICE_NONE;
105	} else {
106		while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
107			if(buf[0] == '#')
108				continue;
109
110			p = buf;
111			while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
112				;
113			if (cp == NULL)
114				continue;
115			do {
116				if (isalpha(cp[0])) {
117					service_order[cc] = get_service_name(cp);
118					if(service_order[cc] != SERVICE_NONE)
119						cc++;
120				}
121				while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
122					;
123			} while(cp != NULL && cc < SERVICE_MAX);
124		}
125		service_order[cc] = SERVICE_NONE;
126		fclose(fd);
127	}
128	service_done = 1;
129}
130
131struct hostent *
132gethostbyname(const char *name)
133{
134	struct hostent *hp = 0;
135	int nserv = 0;
136
137	if (!service_done)
138		init_services();
139
140	while (!hp) {
141		switch (service_order[nserv]) {
142		      case SERVICE_NONE:
143			return NULL;
144		      case SERVICE_HOSTS:
145			hp = _gethostbyhtname(name);
146			break;
147		      case SERVICE_BIND:
148			hp = _gethostbydnsname(name);
149			break;
150		      case SERVICE_NIS:
151			hp = _gethostbynisname(name);
152			break;
153		}
154		nserv++;
155	}
156	return hp;
157}
158
159struct hostent *
160gethostbyaddr(const char *addr, int len, int type)
161{
162	struct hostent *hp = 0;
163	int nserv = 0;
164
165	if (!service_done)
166		init_services();
167
168	while (!hp) {
169		switch (service_order[nserv]) {
170		      case SERVICE_NONE:
171			return 0;
172		      case SERVICE_HOSTS:
173			hp = _gethostbyhtaddr(addr, len, type);
174			break;
175		      case SERVICE_BIND:
176			hp = _gethostbydnsaddr(addr, len, type);
177			break;
178		      case SERVICE_NIS:
179			hp = _gethostbynisaddr(addr, len, type);
180			break;
181		}
182		nserv++;
183	}
184	return hp;
185}
186
187void
188sethostent(stayopen)
189	int stayopen;
190{
191	_sethosthtent(stayopen);
192	_sethostdnsent(stayopen);
193}
194
195void
196endhostent()
197{
198	_endhosthtent();
199	_endhostdnsent();
200}
201