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