xref: /csrg-svn/old/htable/htable.c (revision 13193)
18732Ssam #ifndef lint
2*13193Ssam static char sccsid[] = "@(#)htable.c	4.5 (Berkeley) 06/18/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>
1212227Ssam #include <netdb.h>
1312227Ssam 
149246Ssam #include "htable.h"		/* includes <sys/types.h> */
158732Ssam 
16*13193Ssam #include <sys/socket.h>
179246Ssam #include <netinet/in.h>
188732Ssam 
1912227Ssam #define	INTERNET	10	/* gag */
2012227Ssam 
2112610Smo #define	DATELINES	3	/* these lines usually contain the date */
2212610Smo 
239246Ssam FILE	*hf;			/* hosts file */
249246Ssam FILE	*gf;			/* gateways file */
259246Ssam FILE	*nf;			/* networks file */
269246Ssam 
278732Ssam main(argc, argv)
288732Ssam 	int argc;
298732Ssam 	char *argv[];
308732Ssam {
318732Ssam 	if (argc > 2) {
328732Ssam 		fprintf(stderr, "usage: %s [ input-file ]\n",
338732Ssam 			argv[0]);
348732Ssam 		exit(1);
358732Ssam 	}
368732Ssam 	infile = "(stdin)";
378732Ssam 	if (argc == 2) {
388732Ssam 		infile = argv[1];
398732Ssam 		if (freopen(infile, "r", stdin) == NULL) {
408732Ssam 			perror(infile);
418732Ssam 			exit(1);
428732Ssam 		}
438732Ssam 	}
448732Ssam 	hf = fopen("hosts", "w");
458732Ssam 	if (hf == NULL) {
468732Ssam 		perror("hosts");
478732Ssam 		exit(1);
488732Ssam 	}
499246Ssam 	copylocal(hf, "localhosts");
509246Ssam 	gf = fopen("gateways", "w");
519246Ssam 	if (gf == NULL) {
528732Ssam 		perror("gateways");
538732Ssam 		exit(1);
548732Ssam 	}
559246Ssam 	copylocal(gf, "localgateways");
569246Ssam 	nf = fopen("networks", "w");
579246Ssam 	if (nf == NULL) {
589246Ssam 		perror("networks");
599246Ssam 		exit(1);
609246Ssam 	}
619246Ssam 	copylocal(nf, "localnetworks");
6212610Smo 	copycomments(stdin, hf, DATELINES);
638732Ssam 	exit(yyparse());
648732Ssam }
658732Ssam 
668732Ssam struct name *
678732Ssam newname(str)
688732Ssam 	char *str;
698732Ssam {
708732Ssam 	char *p;
718732Ssam 	struct name *nm;
728732Ssam 
738732Ssam 	p = malloc(strlen(str) + 1);
748732Ssam 	strcpy(p, str);
759246Ssam 	nm = (struct name *)malloc(sizeof (struct name));
768732Ssam 	nm->name_val = p;
778732Ssam 	nm->name_link = NONAME;
788732Ssam 	return (nm);
798732Ssam }
808732Ssam 
818732Ssam char *
828732Ssam lower(str)
838732Ssam 	char *str;
848732Ssam {
858732Ssam 	register char *cp = str;
868732Ssam 
878732Ssam 	while (*cp) {
888732Ssam 		if (isupper(*cp))
898732Ssam 			*cp = tolower(*cp);
908732Ssam 		cp++;
918732Ssam 	}
928732Ssam 	return (str);
938732Ssam }
948732Ssam 
958732Ssam do_entry(keyword, addrlist, namelist, cputype, opsys, protos)
968732Ssam 	int keyword;
978732Ssam 	struct addr *addrlist;
988732Ssam 	struct name *namelist, *cputype, *opsys, *protos;
998732Ssam {
1008732Ssam 	register struct addr *al, *al2;
1019246Ssam 	register struct name *nl;
10212227Ssam 	struct addr *inetal;
10312227Ssam 	int count;
1048732Ssam 
1058732Ssam 	switch (keyword) {
1068732Ssam 
1078732Ssam 	case KW_NET:
1089246Ssam 		nl = namelist;
1099246Ssam 		if (nl == NONAME) {
1109246Ssam 			fprintf(stderr, "htable: net");
1119246Ssam 			putnet(stderr, addrlist->addr_val);
1129246Ssam 			fprintf(stderr, " missing names.\n");
1139246Ssam 			break;
1149246Ssam 		}
1159246Ssam 		fprintf(nf, "%-16.16s", lower(nl->name_val));
1169246Ssam 		al2 = addrlist;
1179246Ssam 		while (al = al2) {
1189246Ssam 			char *cp;
1198732Ssam 
1209246Ssam 			putnet(nf, al->addr_val);
1219246Ssam 			cp = "\t%s";
1229246Ssam 			while (nl = nl->name_link) {
1239246Ssam 				fprintf(nf, cp, lower(nl->name_val));
1249246Ssam 				cp = " %s";
1259246Ssam 			}
1269246Ssam 			putc('\n', nf);
1279246Ssam 			al2 = al->addr_link;
1289246Ssam 			free((char *)al);
1299246Ssam 		}
1309246Ssam 		goto alreadyfree;
1319246Ssam 
1328732Ssam 	case KW_GATEWAY:
13312227Ssam 		/*
13412227Ssam 		 * Kludge here: take only gateways directly connected to
13512227Ssam 		 * the Internet.  Should really calculate closure on
13612227Ssam 		 * connectivity matrix to identify gateways to all networks
13712227Ssam 		 * described in data base, but that's real work.
13812227Ssam 		 */
13912227Ssam 		/* locate Internet address, if one */
14012227Ssam 		for (al = addrlist; al; al = al->addr_link)
14112227Ssam 			if (inet_netof(al->addr_val) == INTERNET)
14212227Ssam 				break;
14312227Ssam 		if (al == NULL)
14412227Ssam 			break;
14512227Ssam 		inetal = al;
14612227Ssam 		for (count = 0, al = al->addr_link; al; al = al->addr_link) {
14712227Ssam 			register int net;
14812227Ssam 			register struct netent *np;
1499246Ssam 
15012227Ssam 			if (al == inetal)
15112227Ssam 				continue;
1529246Ssam 			/* suppress duplicates -- not optimal */
15312227Ssam 			net = inet_netof(al->addr_val);
1549246Ssam 			if (checkgateway(net))
1559246Ssam 				break;
15612227Ssam 			count++;
1579246Ssam 			fprintf(gf, "net ");
15812227Ssam 			np = getnetbyaddr(net, AF_INET);
15912227Ssam 			if (np)
16012227Ssam 				fprintf(gf, "%s", np->n_name);
16112227Ssam 			else
16212227Ssam 				putnet(gf, net);
1639246Ssam 			/* this is a kludge */
16412227Ssam 			fprintf(gf, " gateway %s metric 1 passive\n",
1659246Ssam 				lower(namelist->name_val));
16612227Ssam 			savegateway(net);
16712227Ssam 		}
16812227Ssam 		if (count > 0) {
16912227Ssam 			putaddr(hf, inetal->addr_val);
1709246Ssam 			fprintf(hf, "%s\t# gateway\n",
1719246Ssam 				lower(namelist->name_val));
1729246Ssam 		}
1738732Ssam 		break;
1748732Ssam 
1758732Ssam 	case KW_HOST:
1769246Ssam 		al2 = addrlist;
1779246Ssam 		while (al = al2) {
1789246Ssam 			if (inet_netof(al->addr_val) != LOCALNET) {
1799246Ssam 				char *cp;
1809246Ssam 
1819246Ssam 				putaddr(hf, al->addr_val);
1829246Ssam 				cp = "%s";
1839246Ssam 				for (nl = namelist; nl; nl = nl->name_link) {
1849246Ssam 					fprintf(hf, cp, lower(nl->name_val));
1859246Ssam 					cp = " %s";
1869246Ssam 				}
1878732Ssam 				putc('\n', hf);
1888732Ssam 			}
1898732Ssam 			al2 = al->addr_link;
1909246Ssam 			free((char *)al);
1918732Ssam 		}
1929246Ssam 		goto alreadyfree;
1938732Ssam 
1948732Ssam 	default:
1958732Ssam 		fprintf(stderr, "Unknown keyword: %d.\n", keyword);
1968732Ssam 	}
1979246Ssam 	al2 = addrlist;
1989246Ssam 	while (al = al2)
1999246Ssam 		al2 = al->addr_link, free((char *)al);
2009246Ssam alreadyfree:
2019246Ssam 	freenames(namelist);
2029246Ssam 	freenames(protos);
2038732Ssam }
2048732Ssam 
2059246Ssam copylocal(f, filename)
2069246Ssam 	FILE *f;
2079246Ssam 	char *filename;
2088732Ssam {
2098732Ssam 	register FILE *lhf;
2108732Ssam 	register cc;
2118732Ssam 	char buf[BUFSIZ];
2129246Ssam 	extern int errno;
2138732Ssam 
2149246Ssam 	lhf = fopen(filename, "r");
2158732Ssam 	if (lhf == NULL) {
2169246Ssam 		if (errno != ENOENT) {
2179246Ssam 			perror(filename);
2189246Ssam 			exit(1);
2199246Ssam 		}
2209246Ssam 		fprintf(stderr, "Warning, no %s file.\n", filename);
2218732Ssam 		return;
2228732Ssam 	}
2238732Ssam 	while (cc = fread(buf, 1, sizeof(buf), lhf))
2249246Ssam 		fwrite(buf, 1, cc, f);
2258732Ssam 	fclose(lhf);
2268732Ssam }
2279246Ssam 
22812610Smo copycomments(in, out, ccount)
22912610Smo 	FILE *in, *out;
23012610Smo 	int ccount;
23112610Smo {
23212610Smo 	char buf[BUFSIZ];
23312610Smo 	int length;
23412610Smo 	int count;
23512610Smo 	char *fgets();
23612610Smo 
23712610Smo 	for (count=0; count < ccount; count++) {
23812610Smo 		if ((fgets(buf, sizeof(buf), in) == NULL) || (buf[0] != ';'))
23912610Smo 			return;
24012610Smo 		buf[0] = '#';
24112610Smo 		fputs(buf, out);
24212610Smo 	}
24312610Smo 	return;
24412610Smo }
2459246Ssam #define	UC(b)	(((int)(b))&0xff)
2469246Ssam 
2479246Ssam putnet(f, v)
2489246Ssam 	FILE *f;
2499246Ssam 	u_long v;
2509246Ssam {
2519246Ssam 	register char *a = (char *)&v;
2529246Ssam 
2539246Ssam 	if (UC(a[0]&0x80) == 0)
2549246Ssam 		fprintf(f, "%d", UC(a[0]));
2559246Ssam 	else if ((UC(a[0])&0x40) == 0)
2569246Ssam 		fprintf(f, "%d.%d", UC(a[0]), UC(a[1]));
2579246Ssam 	else
2589246Ssam 		fprintf(f, "%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]));
2599246Ssam }
2609246Ssam 
2619246Ssam putaddr(f, v)
2629246Ssam 	FILE *f;
2639246Ssam 	u_long v;
2649246Ssam {
2659246Ssam 	register char *a = (char *)&v;
2669246Ssam 	char buf[32];
2679246Ssam 
2689246Ssam 	sprintf(buf,"%d.%d.%d.%d", UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]));
2699246Ssam 	fprintf(f, "%-16.16s", buf);
2709246Ssam }
2719246Ssam 
2729246Ssam freenames(list)
2739246Ssam 	struct name *list;
2749246Ssam {
2759246Ssam 	register struct name *nl, *nl2;
2769246Ssam 
2779246Ssam 	nl2 = list;
2789246Ssam 	while (nl = nl2) {
2799246Ssam 		nl2 = nl->name_link;
2809246Ssam 		free(nl->name_val);
2819246Ssam 		free((char *)nl);
2829246Ssam 	}
2839246Ssam }
2849246Ssam struct gateway {
2859246Ssam 	struct	gateway *g_link;
2869246Ssam 	int	g_net;
2879246Ssam };
2889246Ssam 
2899246Ssam struct gateway *gateways = 0;
2909246Ssam 
2919246Ssam checkgateway(net)
2929246Ssam 	register int net;
2939246Ssam {
2949246Ssam 	register struct gateway *gp;
2959246Ssam 
2969246Ssam 	for (gp = gateways; gp; gp = gp->g_link)
2979246Ssam 		if (gp->g_net == net)
2989246Ssam 			return (1);
2999246Ssam 	return (0);
3009246Ssam }
3019246Ssam 
3029246Ssam savegateway(net)
3039246Ssam 	int net;
3049246Ssam {
3059246Ssam 	register struct gateway *gp;
3069246Ssam 
3079246Ssam 	gp = (struct gateway *)malloc(sizeof (struct gateway));
3089246Ssam 	if (gp == 0) {
3099246Ssam 		fprintf(stderr, "htable: out of memory\n");
3109246Ssam 		exit(1);
3119246Ssam 	}
3129246Ssam 	gp->g_link = gateways;
3139246Ssam 	gp->g_net = net;
3149246Ssam 	gateways = gp;
3159246Ssam }
3169246Ssam 
317