xref: /csrg-svn/old/htable/htable.c (revision 12227)
18732Ssam #ifndef lint
2*12227Ssam static char sccsid[] = "@(#)htable.c	4.3 (Berkeley) 05/04/83";
38732Ssam #endif
48732Ssam 
58732Ssam /*
68732Ssam  * htable - convert NIC host table into a UNIX format.
78732Ssam  * NIC format is described in RFC 810, 1 March 1982.
88732Ssam  */
98732Ssam #include <stdio.h>
108732Ssam #include <ctype.h>
119246Ssam #include <errno.h>
12*12227Ssam #include <netdb.h>
13*12227Ssam #include <sys/socket.h>
14*12227Ssam 
159246Ssam #include "htable.h"		/* includes <sys/types.h> */
168732Ssam 
179246Ssam #include <netinet/in.h>
188732Ssam 
19*12227Ssam #define	INTERNET	10	/* gag */
20*12227Ssam 
219246Ssam FILE	*hf;			/* hosts file */
229246Ssam FILE	*gf;			/* gateways file */
239246Ssam FILE	*nf;			/* networks file */
249246Ssam 
258732Ssam main(argc, argv)
268732Ssam 	int argc;
278732Ssam 	char *argv[];
288732Ssam {
298732Ssam 	if (argc > 2) {
308732Ssam 		fprintf(stderr, "usage: %s [ input-file ]\n",
318732Ssam 			argv[0]);
328732Ssam 		exit(1);
338732Ssam 	}
348732Ssam 	infile = "(stdin)";
358732Ssam 	if (argc == 2) {
368732Ssam 		infile = argv[1];
378732Ssam 		if (freopen(infile, "r", stdin) == NULL) {
388732Ssam 			perror(infile);
398732Ssam 			exit(1);
408732Ssam 		}
418732Ssam 	}
428732Ssam 	hf = fopen("hosts", "w");
438732Ssam 	if (hf == NULL) {
448732Ssam 		perror("hosts");
458732Ssam 		exit(1);
468732Ssam 	}
479246Ssam 	copylocal(hf, "localhosts");
489246Ssam 	gf = fopen("gateways", "w");
499246Ssam 	if (gf == NULL) {
508732Ssam 		perror("gateways");
518732Ssam 		exit(1);
528732Ssam 	}
539246Ssam 	copylocal(gf, "localgateways");
549246Ssam 	nf = fopen("networks", "w");
559246Ssam 	if (nf == NULL) {
569246Ssam 		perror("networks");
579246Ssam 		exit(1);
589246Ssam 	}
599246Ssam 	copylocal(nf, "localnetworks");
608732Ssam 	exit(yyparse());
618732Ssam }
628732Ssam 
638732Ssam struct name *
648732Ssam newname(str)
658732Ssam 	char *str;
668732Ssam {
678732Ssam 	char *p;
688732Ssam 	struct name *nm;
698732Ssam 
708732Ssam 	p = malloc(strlen(str) + 1);
718732Ssam 	strcpy(p, str);
729246Ssam 	nm = (struct name *)malloc(sizeof (struct name));
738732Ssam 	nm->name_val = p;
748732Ssam 	nm->name_link = NONAME;
758732Ssam 	return (nm);
768732Ssam }
778732Ssam 
788732Ssam char *
798732Ssam lower(str)
808732Ssam 	char *str;
818732Ssam {
828732Ssam 	register char *cp = str;
838732Ssam 
848732Ssam 	while (*cp) {
858732Ssam 		if (isupper(*cp))
868732Ssam 			*cp = tolower(*cp);
878732Ssam 		cp++;
888732Ssam 	}
898732Ssam 	return (str);
908732Ssam }
918732Ssam 
928732Ssam do_entry(keyword, addrlist, namelist, cputype, opsys, protos)
938732Ssam 	int keyword;
948732Ssam 	struct addr *addrlist;
958732Ssam 	struct name *namelist, *cputype, *opsys, *protos;
968732Ssam {
978732Ssam 	register struct addr *al, *al2;
989246Ssam 	register struct name *nl;
99*12227Ssam 	struct addr *inetal;
100*12227Ssam 	int count;
1018732Ssam 
1028732Ssam 	switch (keyword) {
1038732Ssam 
1048732Ssam 	case KW_NET:
1059246Ssam 		nl = namelist;
1069246Ssam 		if (nl == NONAME) {
1079246Ssam 			fprintf(stderr, "htable: net");
1089246Ssam 			putnet(stderr, addrlist->addr_val);
1099246Ssam 			fprintf(stderr, " missing names.\n");
1109246Ssam 			break;
1119246Ssam 		}
1129246Ssam 		fprintf(nf, "%-16.16s", lower(nl->name_val));
1139246Ssam 		al2 = addrlist;
1149246Ssam 		while (al = al2) {
1159246Ssam 			char *cp;
1168732Ssam 
1179246Ssam 			putnet(nf, al->addr_val);
1189246Ssam 			cp = "\t%s";
1199246Ssam 			while (nl = nl->name_link) {
1209246Ssam 				fprintf(nf, cp, lower(nl->name_val));
1219246Ssam 				cp = " %s";
1229246Ssam 			}
1239246Ssam 			putc('\n', nf);
1249246Ssam 			al2 = al->addr_link;
1259246Ssam 			free((char *)al);
1269246Ssam 		}
1279246Ssam 		goto alreadyfree;
1289246Ssam 
1298732Ssam 	case KW_GATEWAY:
130*12227Ssam 		/*
131*12227Ssam 		 * Kludge here: take only gateways directly connected to
132*12227Ssam 		 * the Internet.  Should really calculate closure on
133*12227Ssam 		 * connectivity matrix to identify gateways to all networks
134*12227Ssam 		 * described in data base, but that's real work.
135*12227Ssam 		 */
136*12227Ssam 		/* locate Internet address, if one */
137*12227Ssam 		for (al = addrlist; al; al = al->addr_link)
138*12227Ssam 			if (inet_netof(al->addr_val) == INTERNET)
139*12227Ssam 				break;
140*12227Ssam 		if (al == NULL)
141*12227Ssam 			break;
142*12227Ssam 		inetal = al;
143*12227Ssam 		for (count = 0, al = al->addr_link; al; al = al->addr_link) {
144*12227Ssam 			register int net;
145*12227Ssam 			register struct netent *np;
1469246Ssam 
147*12227Ssam 			if (al == inetal)
148*12227Ssam 				continue;
1499246Ssam 			/* suppress duplicates -- not optimal */
150*12227Ssam 			net = inet_netof(al->addr_val);
1519246Ssam 			if (checkgateway(net))
1529246Ssam 				break;
153*12227Ssam 			count++;
1549246Ssam 			fprintf(gf, "net ");
155*12227Ssam 			np = getnetbyaddr(net, AF_INET);
156*12227Ssam 			if (np)
157*12227Ssam 				fprintf(gf, "%s", np->n_name);
158*12227Ssam 			else
159*12227Ssam 				putnet(gf, net);
1609246Ssam 			/* this is a kludge */
161*12227Ssam 			fprintf(gf, " gateway %s metric 1 passive\n",
1629246Ssam 				lower(namelist->name_val));
163*12227Ssam 			savegateway(net);
164*12227Ssam 		}
165*12227Ssam 		if (count > 0) {
166*12227Ssam 			putaddr(hf, inetal->addr_val);
1679246Ssam 			fprintf(hf, "%s\t# gateway\n",
1689246Ssam 				lower(namelist->name_val));
1699246Ssam 		}
1708732Ssam 		break;
1718732Ssam 
1728732Ssam 	case KW_HOST:
1739246Ssam 		al2 = addrlist;
1749246Ssam 		while (al = al2) {
1759246Ssam 			if (inet_netof(al->addr_val) != LOCALNET) {
1769246Ssam 				char *cp;
1779246Ssam 
1789246Ssam 				putaddr(hf, al->addr_val);
1799246Ssam 				cp = "%s";
1809246Ssam 				for (nl = namelist; nl; nl = nl->name_link) {
1819246Ssam 					fprintf(hf, cp, lower(nl->name_val));
1829246Ssam 					cp = " %s";
1839246Ssam 				}
1848732Ssam 				putc('\n', hf);
1858732Ssam 			}
1868732Ssam 			al2 = al->addr_link;
1879246Ssam 			free((char *)al);
1888732Ssam 		}
1899246Ssam 		goto alreadyfree;
1908732Ssam 
1918732Ssam 	default:
1928732Ssam 		fprintf(stderr, "Unknown keyword: %d.\n", keyword);
1938732Ssam 	}
1949246Ssam 	al2 = addrlist;
1959246Ssam 	while (al = al2)
1969246Ssam 		al2 = al->addr_link, free((char *)al);
1979246Ssam alreadyfree:
1989246Ssam 	freenames(namelist);
1999246Ssam 	freenames(protos);
2008732Ssam }
2018732Ssam 
2029246Ssam copylocal(f, filename)
2039246Ssam 	FILE *f;
2049246Ssam 	char *filename;
2058732Ssam {
2068732Ssam 	register FILE *lhf;
2078732Ssam 	register cc;
2088732Ssam 	char buf[BUFSIZ];
2099246Ssam 	extern int errno;
2108732Ssam 
2119246Ssam 	lhf = fopen(filename, "r");
2128732Ssam 	if (lhf == NULL) {
2139246Ssam 		if (errno != ENOENT) {
2149246Ssam 			perror(filename);
2159246Ssam 			exit(1);
2169246Ssam 		}
2179246Ssam 		fprintf(stderr, "Warning, no %s file.\n", filename);
2188732Ssam 		return;
2198732Ssam 	}
2208732Ssam 	while (cc = fread(buf, 1, sizeof(buf), lhf))
2219246Ssam 		fwrite(buf, 1, cc, f);
2228732Ssam 	fclose(lhf);
2238732Ssam }
2249246Ssam 
2259246Ssam #define	UC(b)	(((int)(b))&0xff)
2269246Ssam 
2279246Ssam putnet(f, v)
2289246Ssam 	FILE *f;
2299246Ssam 	u_long v;
2309246Ssam {
2319246Ssam 	register char *a = (char *)&v;
2329246Ssam 
2339246Ssam 	if (UC(a[0]&0x80) == 0)
2349246Ssam 		fprintf(f, "%d", UC(a[0]));
2359246Ssam 	else if ((UC(a[0])&0x40) == 0)
2369246Ssam 		fprintf(f, "%d.%d", UC(a[0]), UC(a[1]));
2379246Ssam 	else
2389246Ssam 		fprintf(f, "%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]));
2399246Ssam }
2409246Ssam 
2419246Ssam putaddr(f, v)
2429246Ssam 	FILE *f;
2439246Ssam 	u_long v;
2449246Ssam {
2459246Ssam 	register char *a = (char *)&v;
2469246Ssam 	char buf[32];
2479246Ssam 
2489246Ssam 	sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]));
2499246Ssam 	fprintf(f, "%-16.16s", buf);
2509246Ssam }
2519246Ssam 
2529246Ssam freenames(list)
2539246Ssam 	struct name *list;
2549246Ssam {
2559246Ssam 	register struct name *nl, *nl2;
2569246Ssam 
2579246Ssam 	nl2 = list;
2589246Ssam 	while (nl = nl2) {
2599246Ssam 		nl2 = nl->name_link;
2609246Ssam 		free(nl->name_val);
2619246Ssam 		free((char *)nl);
2629246Ssam 	}
2639246Ssam }
2649246Ssam struct gateway {
2659246Ssam 	struct	gateway *g_link;
2669246Ssam 	int	g_net;
2679246Ssam };
2689246Ssam 
2699246Ssam struct gateway *gateways = 0;
2709246Ssam 
2719246Ssam checkgateway(net)
2729246Ssam 	register int net;
2739246Ssam {
2749246Ssam 	register struct gateway *gp;
2759246Ssam 
2769246Ssam 	for (gp = gateways; gp; gp = gp->g_link)
2779246Ssam 		if (gp->g_net == net)
2789246Ssam 			return (1);
2799246Ssam 	return (0);
2809246Ssam }
2819246Ssam 
2829246Ssam savegateway(net)
2839246Ssam 	int net;
2849246Ssam {
2859246Ssam 	register struct gateway *gp;
2869246Ssam 
2879246Ssam 	gp = (struct gateway *)malloc(sizeof (struct gateway));
2889246Ssam 	if (gp == 0) {
2899246Ssam 		fprintf(stderr, "htable: out of memory\n");
2909246Ssam 		exit(1);
2919246Ssam 	}
2929246Ssam 	gp->g_link = gateways;
2939246Ssam 	gp->g_net = net;
2949246Ssam 	gateways = gp;
2959246Ssam }
2969246Ssam 
297