xref: /freebsd/lib/libc/net/getnetnamadr.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
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)
27 static char rcsid[] = "$FreeBSD$";
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 
44 enum service_type {
45   SERVICE_NONE = 0,
46   SERVICE_BIND,
47   SERVICE_TABLE,
48   SERVICE_NIS };
49 #define SERVICE_MAX	SERVICE_NIS
50 
51 static 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 
68 static enum service_type service_order[SERVICE_MAX + 1];
69 static int service_done = 0;
70 
71 static enum service_type
72 get_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 
82 static void
83 init_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((unsigned char)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 
119 struct netent *
120 getnetbyname(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 
147 struct netent *
148 getnetbyaddr(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 
177 void
178 setnetent(stayopen)
179 	int stayopen;
180 {
181 	_setnethtent(stayopen);
182 	_setnetdnsent(stayopen);
183 }
184 
185 void
186 endnetent()
187 {
188 	_endnethtent();
189 	_endnetdnsent();
190 }
191