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