xref: /plan9/sys/src/cmd/ndb/mkhosts.c (revision 7dd7cddf99dd7472612f1413b4da293630e6b1bc)
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <ndb.h>
5 #include <ip.h>
6 
7 typedef struct x
8 {
9 	Ndbtuple *t;
10 	Ndbtuple *it;
11 	Ndbtuple *nt;
12 } X;
13 
14 X x[4096];
15 int nx;
16 char *domname = "research.att.com";
17 int domnamlen;
18 
19 char*
upper(char * x)20 upper(char *x)
21 {
22 	char *p;
23 	int c;
24 
25 	for(p = x; c = *p; p++)
26 		*p = toupper(c);
27 	return x;
28 }
29 
30 void
printArecord(int fd,X * p)31 printArecord(int fd, X *p)
32 {
33 	Ndbtuple *nt;
34 	char *c;
35 	char *dom = 0;
36 	char *curdom = 0;
37 	int i, cdlen = 0;
38 	int mxweight = 0;
39 
40 	if(p->nt) {
41 		return;
42 	}
43 	for(nt=p->t; nt; nt = nt->entry) {
44 		/* we are only going to handle things in the specified domain */
45 		c = strchr(nt->val, '.');
46 		if (c==0 || strcmp(++c, domname)!=0)
47 			continue;
48 		i = c - nt->val - 1;
49 		if(strcmp(nt->attr, "dom") == 0) {
50 			curdom = nt->val;
51 			cdlen = i;
52 			if (dom == 0) {
53 				dom = curdom;
54 				fprint(fd, "%-.*s%.*s	IN A	%s\n", i, nt->val, 15-i, "               ", p->it->val);
55 			} else
56 				fprint(fd, "%-.*s%.*s	IN CNAME	%s.\n", i, nt->val, 15-i, "               ", dom);
57 		} else if(strcmp(nt->attr, "mx") == 0) {
58 			if (curdom != 0)
59 				fprint(fd, "%-.*s%.*s	MX	%d	%s.\n", cdlen, curdom, 15-cdlen, "               ", mxweight++, nt->val);
60 		}
61 	}
62 }
63 
64 void
printentry(int fd,X * p)65 printentry(int fd, X *p)
66 {
67 	Ndbtuple *nt;
68 
69 	if(p->nt)
70 		return;
71 	fprint(fd, "%s	", p->it->val);
72 	for(nt = p->t; nt; nt = nt->entry)
73 		if(strcmp(nt->attr, "dom") == 0)
74 			fprint(fd, " %s", nt->val);
75 	for(nt = p->t; nt; nt = nt->entry)
76 		if(strcmp(nt->attr, "sys") == 0)
77 			fprint(fd, " %s", nt->val);
78 	fprint(fd, "\n");
79 }
80 
81 void
printsys(int fd,X * p)82 printsys(int fd, X *p)
83 {
84 	Ndbtuple *nt;
85 
86 	for(nt = p->t; nt; nt = nt->entry)
87 		if(strcmp(nt->attr, "dom") == 0)
88 			fprint(fd, "%s\n", nt->val);
89 }
90 
91 void
printtxt(int fd,X * p)92 printtxt(int fd, X *p)
93 {
94 	int i;
95 	Ndbtuple *nt;
96 
97 	if(p->nt){
98 		for(;;){
99 			i = strlen(p->it->val);
100 			if(strcmp(p->it->val+i-2, ".0") == 0)
101 				p->it->val[i-2] = 0;
102 			else
103 				break;
104 		}
105 		fprint(fd, "\nNET : %s : %s\n", p->it->val, upper(p->nt->val));
106 		return;
107 	}
108 	fprint(fd, "HOST : %s :", p->it->val);
109 	i = 0;
110 	for(nt = p->t; nt; nt = nt->entry)
111 		if(strcmp(nt->attr, "dom") == 0){
112 			if(i++ == 0)
113 				fprint(fd, " %s", upper(nt->val));
114 			else
115 				fprint(fd, ", %s", upper(nt->val));
116 		}
117 	fprint(fd, "\n");
118 }
119 
120 void
parse(char * file)121 parse(char *file)
122 {
123 	int i;
124 	Ndb *db;
125 	Ndbtuple *t, *nt, *tt, *ipnett;
126 	char *p;
127 
128 	db = ndbopen(file);
129 	if(db == 0)
130 		exits("no database");
131 	while(t = ndbparse(db)){
132 		for(nt = t; nt; nt = nt->entry){
133 			if(strcmp(nt->attr, "ip") == 0)
134 				break;
135 			if(strcmp(nt->attr, "flavor") == 0
136 			&& strcmp(nt->val, "console") == 0)
137 				return;
138 		}
139 		if(nt == 0){
140 			ndbfree(t);
141 			continue;
142 		}
143 
144 		/* dump anything not on our nets */
145 		ipnett = 0;
146 		for(tt = t; tt; tt = tt->entry){
147 			if(strcmp(tt->attr, "ipnet") == 0){
148 				ipnett = tt;
149 				break;
150 			}
151 			if(strcmp(tt->attr, "dom") == 0){
152 				i = strlen(tt->val);
153 				p = tt->val+i-domnamlen;
154 				if(p >= tt->val && strcmp(p, domname) == 0)
155 					break;
156 			}
157 		}
158 		if(tt == 0){
159 			ndbfree(t);
160 			continue;
161 		}
162 
163 		for(; nt; nt = nt->entry){
164 			if(strcmp(nt->attr, "ip") != 0)
165 				continue;
166 			x[nx].it = nt;
167 			x[nx].nt = ipnett;
168 			x[nx++].t = t;
169 		}
170 	}
171 }
172 
173 void
main(int argc,char * argv[])174 main(int argc, char *argv[])
175 {
176 	int i, fd;
177 	char fn[128];
178 
179 	if (argc>1)
180 		domname = argv[1];
181 	domnamlen = strlen(domname);
182 	if(argc > 2){
183 		for(i = 2; i < argc; i++)
184 			parse(argv[i]);
185 	} else {
186 		parse("/lib/ndb/local");
187 		parse("/lib/ndb/friends");
188 	}
189 
190 //	sprint(fn, "/lib/ndb/hosts.%-.21s", domname);
191 //	fd = create(fn, OWRITE, 0664);
192 //	if(fd < 0){
193 //		fprint(2, "can't create %s: %r\n", fn);
194 //		exits("boom");
195 //	}
196 //	for(i = 0; i < nx; i++)
197 //		printentry(fd, &x[i]);
198 //	close(fd);
199 //
200 
201 	sprint(fn, "/lib/ndb/db.%-.24s", domname);
202 	fd = create(fn, OWRITE, 0664);
203 	if(fd < 0){
204 		fprint(2, "can't create %s: %r\n", fn);
205 		exits("boom");
206 	}
207 	fprint(fd, "; This file is generated automatically, do not edit!\n");
208 	for(i = 0; i < nx; i++)
209 		printArecord(fd, &x[i]);
210 	close(fd);
211 
212 	sprint(fn, "/lib/ndb/equiv.%-.21s", domname);
213 	fd = create(fn, OWRITE, 0664);
214 	if(fd < 0){
215 		fprint(2, "can't create %s: %r\n", fn);
216 		exits("boom");
217 	}
218 	for(i = 0; i < nx; i++)
219 		printsys(fd, &x[i]);
220 	close(fd);
221 
222 	sprint(fn, "/lib/ndb/txt.%-.23s", domname);
223 	fd = create(fn, OWRITE, 0664);
224 	if(fd < 0){
225 		fprint(2, "can't create %s: %r\n", fn);
226 		exits("boom");
227 	}
228 	for(i = 0; i < nx; i++)
229 		printtxt(fd, &x[i]);
230 	close(fd);
231 
232 	exits(0);
233 }
234