Commit | Line | Data |
---|---|---|
dd020e70 | 1 | #ifndef lint |
f7a7a9a9 | 2 | static char sccsid[] = "@(#)htable.c 4.5 (Berkeley) %G%"; |
dd020e70 SL |
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> | |
5494cf94 | 11 | #include <errno.h> |
7df00d98 | 12 | #include <netdb.h> |
7df00d98 | 13 | |
5494cf94 | 14 | #include "htable.h" /* includes <sys/types.h> */ |
dd020e70 | 15 | |
f7a7a9a9 | 16 | #include <sys/socket.h> |
5494cf94 SL |
17 | #include <netinet/in.h> |
18 | ||
7df00d98 SL |
19 | #define INTERNET 10 /* gag */ |
20 | ||
1750308c MD |
21 | #define DATELINES 3 /* these lines usually contain the date */ |
22 | ||
5494cf94 SL |
23 | FILE *hf; /* hosts file */ |
24 | FILE *gf; /* gateways file */ | |
25 | FILE *nf; /* networks file */ | |
dd020e70 SL |
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 | } | |
5494cf94 SL |
49 | copylocal(hf, "localhosts"); |
50 | gf = fopen("gateways", "w"); | |
51 | if (gf == NULL) { | |
dd020e70 SL |
52 | perror("gateways"); |
53 | exit(1); | |
54 | } | |
5494cf94 SL |
55 | copylocal(gf, "localgateways"); |
56 | nf = fopen("networks", "w"); | |
57 | if (nf == NULL) { | |
58 | perror("networks"); | |
59 | exit(1); | |
60 | } | |
61 | copylocal(nf, "localnetworks"); | |
1750308c | 62 | copycomments(stdin, hf, DATELINES); |
dd020e70 SL |
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); | |
5494cf94 | 75 | nm = (struct name *)malloc(sizeof (struct name)); |
dd020e70 SL |
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; | |
5494cf94 | 101 | register struct name *nl; |
7df00d98 SL |
102 | struct addr *inetal; |
103 | int count; | |
dd020e70 SL |
104 | |
105 | switch (keyword) { | |
106 | ||
107 | case KW_NET: | |
5494cf94 SL |
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; | |
dd020e70 SL |
131 | |
132 | case KW_GATEWAY: | |
7df00d98 SL |
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; | |
5494cf94 | 149 | |
7df00d98 SL |
150 | if (al == inetal) |
151 | continue; | |
5494cf94 | 152 | /* suppress duplicates -- not optimal */ |
7df00d98 | 153 | net = inet_netof(al->addr_val); |
5494cf94 SL |
154 | if (checkgateway(net)) |
155 | break; | |
7df00d98 | 156 | count++; |
5494cf94 | 157 | fprintf(gf, "net "); |
7df00d98 SL |
158 | np = getnetbyaddr(net, AF_INET); |
159 | if (np) | |
160 | fprintf(gf, "%s", np->n_name); | |
161 | else | |
162 | putnet(gf, net); | |
5494cf94 | 163 | /* this is a kludge */ |
7df00d98 | 164 | fprintf(gf, " gateway %s metric 1 passive\n", |
5494cf94 | 165 | lower(namelist->name_val)); |
7df00d98 SL |
166 | savegateway(net); |
167 | } | |
168 | if (count > 0) { | |
169 | putaddr(hf, inetal->addr_val); | |
5494cf94 SL |
170 | fprintf(hf, "%s\t# gateway\n", |
171 | lower(namelist->name_val)); | |
5494cf94 | 172 | } |
dd020e70 SL |
173 | break; |
174 | ||
175 | case KW_HOST: | |
5494cf94 SL |
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 | } | |
dd020e70 SL |
187 | putc('\n', hf); |
188 | } | |
189 | al2 = al->addr_link; | |
5494cf94 | 190 | free((char *)al); |
dd020e70 | 191 | } |
5494cf94 | 192 | goto alreadyfree; |
dd020e70 SL |
193 | |
194 | default: | |
195 | fprintf(stderr, "Unknown keyword: %d.\n", keyword); | |
196 | } | |
5494cf94 SL |
197 | al2 = addrlist; |
198 | while (al = al2) | |
199 | al2 = al->addr_link, free((char *)al); | |
200 | alreadyfree: | |
201 | freenames(namelist); | |
202 | freenames(protos); | |
dd020e70 SL |
203 | } |
204 | ||
5494cf94 SL |
205 | copylocal(f, filename) |
206 | FILE *f; | |
207 | char *filename; | |
dd020e70 SL |
208 | { |
209 | register FILE *lhf; | |
210 | register cc; | |
211 | char buf[BUFSIZ]; | |
5494cf94 | 212 | extern int errno; |
dd020e70 | 213 | |
5494cf94 | 214 | lhf = fopen(filename, "r"); |
dd020e70 | 215 | if (lhf == NULL) { |
5494cf94 SL |
216 | if (errno != ENOENT) { |
217 | perror(filename); | |
218 | exit(1); | |
219 | } | |
220 | fprintf(stderr, "Warning, no %s file.\n", filename); | |
dd020e70 SL |
221 | return; |
222 | } | |
223 | while (cc = fread(buf, 1, sizeof(buf), lhf)) | |
5494cf94 | 224 | fwrite(buf, 1, cc, f); |
dd020e70 SL |
225 | fclose(lhf); |
226 | } | |
5494cf94 | 227 | |
1750308c MD |
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 | } | |
5494cf94 SL |
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 |