getnetnamadr.c revision 26974
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 rcsid[] = "$Id: getnetnamadr.c,v 1.9 1997/02/22 15:00:12 peter Exp $";
28#endif /* LIBC_SCCS and not lint */
29
30#include <sys/param.h>
31#include <sys/socket.h>
32#include <netinet/in.h>
33#include <arpa/inet.h>
34#include <netdb.h>
35#include <stdio.h>
36#include <ctype.h>
37#include <errno.h>
38#include <string.h>
39
40#ifndef _PATH_NETCONF
41#define _PATH_NETCONF	"/etc/host.conf"
42#endif
43
44enum service_type {
45  SERVICE_NONE = 0,
46  SERVICE_BIND,
47  SERVICE_TABLE,
48  SERVICE_NIS };
49#define SERVICE_MAX	SERVICE_NIS
50
51static struct {
52  const char *name;
53  enum service_type type;
54} service_names[] = {
55  { "hosts", SERVICE_TABLE },
56  { "/etc/hosts", SERVICE_TABLE },
57  { "hosttable", SERVICE_TABLE },
58  { "htable", SERVICE_TABLE },
59  { "bind", SERVICE_BIND },
60  { "dns", SERVICE_BIND },
61  { "domain", SERVICE_BIND },
62  { "yp", SERVICE_NIS },
63  { "yellowpages", SERVICE_NIS },
64  { "nis", SERVICE_NIS },
65  { 0, SERVICE_NONE }
66};
67
68static enum service_type service_order[SERVICE_MAX + 1];
69static int service_done = 0;
70
71static enum service_type
72get_service_name(const char *name) {
73	int i;
74	for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
75		if(!strcasecmp(name, service_names[i].name)) {
76			return service_names[i].type;
77		}
78	}
79	return SERVICE_NONE;
80}
81
82static void
83init_services()
84{
85	char *cp, *p, buf[BUFSIZ];
86	register int cc = 0;
87	FILE *fd;
88
89	if ((fd = (FILE *)fopen(_PATH_NETCONF, "r")) == NULL) {
90				/* make some assumptions */
91		service_order[0] = SERVICE_TABLE;
92		service_order[1] = SERVICE_NONE;
93	} else {
94		while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
95			if(buf[0] == '#')
96				continue;
97
98			p = buf;
99			while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
100				;
101			if (cp == NULL)
102				continue;
103			do {
104				if (isalpha(cp[0])) {
105					service_order[cc] = get_service_name(cp);
106					if(service_order[cc] != SERVICE_NONE)
107						cc++;
108				}
109				while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
110					;
111			} while(cp != NULL && cc < SERVICE_MAX);
112		}
113		service_order[cc] = SERVICE_NONE;
114		fclose(fd);
115	}
116	service_done = 1;
117}
118
119struct netent *
120getnetbyname(const char *name)
121{
122	struct netent *hp = 0;
123	int nserv = 0;
124
125	if (!service_done)
126		init_services();
127
128	while (!hp) {
129		switch (service_order[nserv]) {
130		      case SERVICE_NONE:
131			return NULL;
132		      case SERVICE_TABLE:
133			hp = _getnetbyhtname(name);
134			break;
135		      case SERVICE_BIND:
136			hp = _getnetbydnsname(name);
137			break;
138		      case SERVICE_NIS:
139			hp = _getnetbynisname(name);
140			break;
141		}
142		nserv++;
143	}
144	return hp;
145}
146
147struct netent *
148getnetbyaddr(addr, af)
149	u_long addr;
150	int af;
151{
152	struct netent *hp = 0;
153	int nserv = 0;
154
155	if (!service_done)
156		init_services();
157
158	while (!hp) {
159		switch (service_order[nserv]) {
160		      case SERVICE_NONE:
161			return 0;
162		      case SERVICE_TABLE:
163			hp = _getnetbyhtaddr(addr, af);
164			break;
165		      case SERVICE_BIND:
166			hp = _getnetbydnsaddr(addr, af);
167			break;
168		      case SERVICE_NIS:
169			hp = _getnetbynisaddr(addr, af);
170			break;
171		}
172		nserv++;
173	}
174	return hp;
175}
176
177void
178setnetent(stayopen)
179	int stayopen;
180{
181	_setnethtent(stayopen);
182	_setnetdnsent(stayopen);
183}
184
185void
186endnetent()
187{
188	_endnethtent();
189	_endnetdnsent();
190}
191