xref: /original-bsd/old/htable/htable.c (revision 92d3de31)
1 #ifndef lint
2 static char sccsid[] = "@(#)htable.c	4.3 (Berkeley) 05/04/83";
3 #endif
4 
5 /*
6  * htable - convert NIC host table into a UNIX format.
7  * NIC format is described in RFC 810, 1 March 1982.
8  */
9 #include <stdio.h>
10 #include <ctype.h>
11 #include <errno.h>
12 #include <netdb.h>
13 #include <sys/socket.h>
14 
15 #include "htable.h"		/* includes <sys/types.h> */
16 
17 #include <netinet/in.h>
18 
19 #define	INTERNET	10	/* gag */
20 
21 FILE	*hf;			/* hosts file */
22 FILE	*gf;			/* gateways file */
23 FILE	*nf;			/* networks file */
24 
25 main(argc, argv)
26 	int argc;
27 	char *argv[];
28 {
29 	if (argc > 2) {
30 		fprintf(stderr, "usage: %s [ input-file ]\n",
31 			argv[0]);
32 		exit(1);
33 	}
34 	infile = "(stdin)";
35 	if (argc == 2) {
36 		infile = argv[1];
37 		if (freopen(infile, "r", stdin) == NULL) {
38 			perror(infile);
39 			exit(1);
40 		}
41 	}
42 	hf = fopen("hosts", "w");
43 	if (hf == NULL) {
44 		perror("hosts");
45 		exit(1);
46 	}
47 	copylocal(hf, "localhosts");
48 	gf = fopen("gateways", "w");
49 	if (gf == NULL) {
50 		perror("gateways");
51 		exit(1);
52 	}
53 	copylocal(gf, "localgateways");
54 	nf = fopen("networks", "w");
55 	if (nf == NULL) {
56 		perror("networks");
57 		exit(1);
58 	}
59 	copylocal(nf, "localnetworks");
60 	exit(yyparse());
61 }
62 
63 struct name *
64 newname(str)
65 	char *str;
66 {
67 	char *p;
68 	struct name *nm;
69 
70 	p = malloc(strlen(str) + 1);
71 	strcpy(p, str);
72 	nm = (struct name *)malloc(sizeof (struct name));
73 	nm->name_val = p;
74 	nm->name_link = NONAME;
75 	return (nm);
76 }
77 
78 char *
79 lower(str)
80 	char *str;
81 {
82 	register char *cp = str;
83 
84 	while (*cp) {
85 		if (isupper(*cp))
86 			*cp = tolower(*cp);
87 		cp++;
88 	}
89 	return (str);
90 }
91 
92 do_entry(keyword, addrlist, namelist, cputype, opsys, protos)
93 	int keyword;
94 	struct addr *addrlist;
95 	struct name *namelist, *cputype, *opsys, *protos;
96 {
97 	register struct addr *al, *al2;
98 	register struct name *nl;
99 	struct addr *inetal;
100 	int count;
101 
102 	switch (keyword) {
103 
104 	case KW_NET:
105 		nl = namelist;
106 		if (nl == NONAME) {
107 			fprintf(stderr, "htable: net");
108 			putnet(stderr, addrlist->addr_val);
109 			fprintf(stderr, " missing names.\n");
110 			break;
111 		}
112 		fprintf(nf, "%-16.16s", lower(nl->name_val));
113 		al2 = addrlist;
114 		while (al = al2) {
115 			char *cp;
116 
117 			putnet(nf, al->addr_val);
118 			cp = "\t%s";
119 			while (nl = nl->name_link) {
120 				fprintf(nf, cp, lower(nl->name_val));
121 				cp = " %s";
122 			}
123 			putc('\n', nf);
124 			al2 = al->addr_link;
125 			free((char *)al);
126 		}
127 		goto alreadyfree;
128 
129 	case KW_GATEWAY:
130 		/*
131 		 * Kludge here: take only gateways directly connected to
132 		 * the Internet.  Should really calculate closure on
133 		 * connectivity matrix to identify gateways to all networks
134 		 * described in data base, but that's real work.
135 		 */
136 		/* locate Internet address, if one */
137 		for (al = addrlist; al; al = al->addr_link)
138 			if (inet_netof(al->addr_val) == INTERNET)
139 				break;
140 		if (al == NULL)
141 			break;
142 		inetal = al;
143 		for (count = 0, al = al->addr_link; al; al = al->addr_link) {
144 			register int net;
145 			register struct netent *np;
146 
147 			if (al == inetal)
148 				continue;
149 			/* suppress duplicates -- not optimal */
150 			net = inet_netof(al->addr_val);
151 			if (checkgateway(net))
152 				break;
153 			count++;
154 			fprintf(gf, "net ");
155 			np = getnetbyaddr(net, AF_INET);
156 			if (np)
157 				fprintf(gf, "%s", np->n_name);
158 			else
159 				putnet(gf, net);
160 			/* this is a kludge */
161 			fprintf(gf, " gateway %s metric 1 passive\n",
162 				lower(namelist->name_val));
163 			savegateway(net);
164 		}
165 		if (count > 0) {
166 			putaddr(hf, inetal->addr_val);
167 			fprintf(hf, "%s\t# gateway\n",
168 				lower(namelist->name_val));
169 		}
170 		break;
171 
172 	case KW_HOST:
173 		al2 = addrlist;
174 		while (al = al2) {
175 			if (inet_netof(al->addr_val) != LOCALNET) {
176 				char *cp;
177 
178 				putaddr(hf, al->addr_val);
179 				cp = "%s";
180 				for (nl = namelist; nl; nl = nl->name_link) {
181 					fprintf(hf, cp, lower(nl->name_val));
182 					cp = " %s";
183 				}
184 				putc('\n', hf);
185 			}
186 			al2 = al->addr_link;
187 			free((char *)al);
188 		}
189 		goto alreadyfree;
190 
191 	default:
192 		fprintf(stderr, "Unknown keyword: %d.\n", keyword);
193 	}
194 	al2 = addrlist;
195 	while (al = al2)
196 		al2 = al->addr_link, free((char *)al);
197 alreadyfree:
198 	freenames(namelist);
199 	freenames(protos);
200 }
201 
202 copylocal(f, filename)
203 	FILE *f;
204 	char *filename;
205 {
206 	register FILE *lhf;
207 	register cc;
208 	char buf[BUFSIZ];
209 	extern int errno;
210 
211 	lhf = fopen(filename, "r");
212 	if (lhf == NULL) {
213 		if (errno != ENOENT) {
214 			perror(filename);
215 			exit(1);
216 		}
217 		fprintf(stderr, "Warning, no %s file.\n", filename);
218 		return;
219 	}
220 	while (cc = fread(buf, 1, sizeof(buf), lhf))
221 		fwrite(buf, 1, cc, f);
222 	fclose(lhf);
223 }
224 
225 #define	UC(b)	(((int)(b))&0xff)
226 
227 putnet(f, v)
228 	FILE *f;
229 	u_long v;
230 {
231 	register char *a = (char *)&v;
232 
233 	if (UC(a[0]&0x80) == 0)
234 		fprintf(f, "%d", UC(a[0]));
235 	else if ((UC(a[0])&0x40) == 0)
236 		fprintf(f, "%d.%d", UC(a[0]), UC(a[1]));
237 	else
238 		fprintf(f, "%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]));
239 }
240 
241 putaddr(f, v)
242 	FILE *f;
243 	u_long v;
244 {
245 	register char *a = (char *)&v;
246 	char buf[32];
247 
248 	sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]));
249 	fprintf(f, "%-16.16s", buf);
250 }
251 
252 freenames(list)
253 	struct name *list;
254 {
255 	register struct name *nl, *nl2;
256 
257 	nl2 = list;
258 	while (nl = nl2) {
259 		nl2 = nl->name_link;
260 		free(nl->name_val);
261 		free((char *)nl);
262 	}
263 }
264 struct gateway {
265 	struct	gateway *g_link;
266 	int	g_net;
267 };
268 
269 struct gateway *gateways = 0;
270 
271 checkgateway(net)
272 	register int net;
273 {
274 	register struct gateway *gp;
275 
276 	for (gp = gateways; gp; gp = gp->g_link)
277 		if (gp->g_net == net)
278 			return (1);
279 	return (0);
280 }
281 
282 savegateway(net)
283 	int net;
284 {
285 	register struct gateway *gp;
286 
287 	gp = (struct gateway *)malloc(sizeof (struct gateway));
288 	if (gp == 0) {
289 		fprintf(stderr, "htable: out of memory\n");
290 		exit(1);
291 	}
292 	gp->g_link = gateways;
293 	gp->g_net = net;
294 	gateways = gp;
295 }
296 
297