|
|
1.1 root 1: /*
2: * htable - convert NIC host table into a UNIX format.
3: * NIC format is described in RFC 810, 1 March 1982.
4: */
5: #include <stdio.h>
6: #include <ctype.h>
7: #include <errno.h>
8: #include <sys/types.h>
9:
10: #include "htable.h"
11:
12:
13: #define DATELINES 3 /* these lines usually contain the date */
14: #define MAXNETS 30 /* array size for local, connected nets */
15:
16: FILE *hf; /* hosts file */
17: FILE *gf; /* gateways file */
18: FILE *nf; /* networks file */
19: struct gateway *savegateway(), *gatewayto();
20:
21: int connected_nets[MAXNETS];
22: int nconnected;
23: int local_nets[MAXNETS];
24: int nlocal;
25: char *myname;
26:
27: main(argc, argv)
28: int argc;
29: char *argv[];
30: {
31: int errs;
32:
33: infile = "(stdin)";
34: myname = argv[0];
35: argc--;
36: argv++;
37: while (argc--) {
38: if (*argv[0] == '-') {
39: switch (argv[0][1]) {
40: case 'c':
41: nconnected = addlocal(argv[1], connected_nets);
42: argv++;
43: argc--;
44: break;
45: case 'l':
46: nlocal = addlocal(argv[1], local_nets);
47: argv++;
48: argc--;
49: break;
50: default:
51: usage();
52: /*NOTREACHED*/
53: }
54: } else {
55: infile = argv[0];
56: if (freopen(infile, "r", stdin) == NULL) {
57: perror(infile);
58: exit(1);
59: }
60: }
61: argv++;
62: }
63: hf = fopen("hosts", "w");
64: if (hf == NULL) {
65: perror("hosts");
66: exit(1);
67: }
68: copylocal(hf, "localhosts");
69: gf = fopen("gateways", "w");
70: if (gf == NULL) {
71: perror("gateways");
72: exit(1);
73: }
74: nf = fopen("networks", "w");
75: if (nf == NULL) {
76: perror("networks");
77: exit(1);
78: }
79: copylocal(nf, "localnetworks");
80: copycomments(stdin, hf, DATELINES);
81: errs = yyparse();
82: exit(errs);
83: }
84:
85: usage()
86: {
87: fprintf(stderr,
88: "usage: %s [ -c connected-nets ] [-l local-nets ] [ input-file ]\n",
89: myname);
90: exit(1);
91: }
92:
93: /*
94: * Turn a comma-separated list of network names or numbers in dot notation
95: * (e.g. "arpanet, 128.32") into an array of net numbers.
96: */
97: addlocal(arg, nets)
98: char *arg;
99: int *nets;
100: {
101: register char *p, c;
102: register int nfound = 0;
103:
104: do {
105: p = arg;
106: while (*p && *p != ',' && !isspace(*p))
107: p++;
108: c = *p;
109: *p = 0;
110: while (*arg && isspace(*arg))
111: arg++;
112: if (*arg == 0)
113: continue;
114: if (nfound == MAXNETS) {
115: fprintf(stderr, "%s: Too many networks in list\n",
116: myname);
117: return (nfound);
118: }
119: if (getnetaddr(arg, &nets[nfound]))
120: nfound++;
121: else {
122: fprintf(stderr, "%s: %s: unknown network\n",
123: myname, arg);
124: exit(1);
125: }
126: arg = p + 1;
127: } while (c);
128: return (nfound);
129: }
130:
131: struct name *
132: newname(str)
133: char *str;
134: {
135: char *p;
136: struct name *nm;
137:
138: p = malloc(strlen(str) + 1);
139: strcpy(p, str);
140: nm = (struct name *)malloc(sizeof (struct name));
141: nm->name_val = p;
142: nm->name_link = NONAME;
143: return (nm);
144: }
145:
146: char *
147: lower(str)
148: char *str;
149: {
150: register char *cp = str;
151:
152: while (*cp) {
153: if (isupper(*cp))
154: *cp = tolower(*cp);
155: cp++;
156: }
157: return (str);
158: }
159:
160: do_entry(keyword, addrlist, namelist, cputype, opsys, protos)
161: int keyword;
162: struct addr *addrlist;
163: struct name *namelist, *cputype, *opsys, *protos;
164: {
165: register struct addr *al, *al2;
166: register struct name *nl;
167: struct addr *connect_addr;
168: char *cp;
169:
170: switch (keyword) {
171:
172: case KW_NET:
173: nl = namelist;
174: if (nl == NONAME) {
175: fprintf(stderr, "htable: net");
176: putnet(stderr, inet_netof(addrlist->addr_val));
177: fprintf(stderr, " missing names.\n");
178: break;
179: }
180: fprintf(nf, "%-16.16s", lower(nl->name_val));
181: al2 = addrlist;
182: while (al = al2) {
183: char *cp;
184:
185: putnet(nf, inet_netof(al->addr_val));
186: cp = "\t%s";
187: while (nl = nl->name_link) {
188: fprintf(nf, cp, lower(nl->name_val));
189: cp = " %s";
190: }
191: putc('\n', nf);
192: al2 = al->addr_link;
193: free((char *)al);
194: }
195: break;
196:
197: case KW_GATEWAY:
198: /* locate locally connected address, if one */
199: for (al = addrlist; al; al = al->addr_link)
200: if (connectedto(inet_netof(al->addr_val)))
201: break;
202: if (al == NULL) {
203: /*
204: * Not connected to known networks. Save for later.
205: */
206: struct gateway *gw, *firstgw = (struct gateway *) NULL;
207:
208: for (al = addrlist; al; al = al->addr_link) {
209: register int net;
210:
211: net = inet_netof(al->addr_val);
212: gw = savegateway(namelist, net,
213: al->addr_val, 0);
214: if (firstgw == (struct gateway *) NULL)
215: firstgw = gw;
216: gw->g_firstent = firstgw;
217: }
218: freeaddrs(addrlist);
219: goto dontfree;
220: }
221: /*
222: * Connected to a known network.
223: * Mark this as the gateway to all other networks
224: * that are on the addrlist (unless we already have
225: * gateways to them).
226: */
227: connect_addr = al;
228: for (al = addrlist; al; al = al->addr_link) {
229: register int net;
230:
231: /* suppress duplicates -- not optimal */
232: net = inet_netof(al->addr_val);
233: if (connectedto(net) || gatewayto(net))
234: continue;
235: printgateway(net, namelist->name_val, 1);
236: (void) savegateway(namelist, net, al->addr_val, 1);
237: }
238: /*
239: * Put the gateway in the hosts file.
240: */
241: putaddr(hf, connect_addr->addr_val);
242: cp = "%s";
243: for (nl = namelist; nl; nl = nl->name_link) {
244: fprintf(hf, cp, lower(nl->name_val));
245: cp = " %s";
246: }
247: fprintf(hf, "\t# gateway\n");
248: freeaddrs(addrlist);
249: goto dontfree;
250:
251: case KW_HOST:
252: al2 = addrlist;
253: while (al = al2) {
254: if (!local(inet_netof(al->addr_val))) {
255: char *cp;
256:
257: putaddr(hf, al->addr_val);
258: cp = "%s";
259: for (nl = namelist; nl; nl = nl->name_link) {
260: fprintf(hf, cp, lower(nl->name_val));
261: cp = " %s";
262: }
263: putc('\n', hf);
264: }
265: al2 = al->addr_link;
266: free((char *)al);
267: }
268: break;
269:
270: default:
271: fprintf(stderr, "Unknown keyword: %d.\n", keyword);
272: }
273: freenames(namelist);
274: dontfree:
275: freenames(protos);
276: }
277:
278: copylocal(f, filename)
279: FILE *f;
280: char *filename;
281: {
282: register FILE *lhf;
283: register cc;
284: char buf[BUFSIZ];
285: extern int errno;
286:
287: lhf = fopen(filename, "r");
288: if (lhf == NULL) {
289: if (errno != ENOENT) {
290: perror(filename);
291: exit(1);
292: }
293: fprintf(stderr, "Warning, no %s file.\n", filename);
294: return;
295: }
296: while (cc = fread(buf, 1, sizeof(buf), lhf))
297: fwrite(buf, 1, cc, f);
298: fclose(lhf);
299: }
300:
301: copycomments(in, out, ccount)
302: FILE *in, *out;
303: int ccount;
304: {
305: int count;
306: char buf[BUFSIZ], *fgets();
307:
308: for (count=0; count < ccount; count++) {
309: if ((fgets(buf, sizeof(buf), in) == NULL) || (buf[0] != ';'))
310: return;
311: buf[0] = '#';
312: fputs(buf, out);
313: }
314: return;
315: }
316: #define UC(b) (((int)(b))&0xff)
317:
318: /*
319: * Print network number in internet-standard dot notation;
320: * v is in host byte order.
321: */
322: putnet(f, v)
323: FILE *f;
324: register int v;
325: {
326: if (v < 128)
327: fprintf(f, "%d", v);
328: else if (v < 65536)
329: fprintf(f, "%d.%d", UC(v >> 8), UC(v));
330: else
331: fprintf(f, "%d.%d.%d", UC(v >> 16), UC(v >> 8), UC(v));
332: }
333:
334: putaddr(f, v)
335: FILE *f;
336: in_addr v;
337: {
338: fprintf(f, "%-16.16s", inet_ntoa(v));
339: }
340:
341: freenames(list)
342: struct name *list;
343: {
344: register struct name *nl, *nl2;
345:
346: nl2 = list;
347: while (nl = nl2) {
348: nl2 = nl->name_link;
349: free(nl->name_val);
350: free((char *)nl);
351: }
352: }
353:
354: freeaddrs(list)
355: struct addr *list;
356: {
357: register struct addr *al, *al2;
358:
359: al2 = list;
360: while (al = al2)
361: al2 = al->addr_link, free((char *)al);
362: }
363:
364: struct gateway *gateways = 0;
365: struct gateway *lastgateway = 0;
366:
367: struct gateway *
368: gatewayto(net)
369: register int net;
370: {
371: register struct gateway *gp;
372:
373: for (gp = gateways; gp; gp = gp->g_link)
374: if ((gp->g_net == net) && (gp->g_metric > 0))
375: return (gp);
376: return ((struct gateway *) NULL);
377: }
378:
379: struct gateway *
380: savegateway(namelist, net, addr, metric)
381: struct name *namelist;
382: in_addr addr;
383: int net, metric;
384: {
385: register struct gateway *gp;
386:
387: gp = (struct gateway *)malloc(sizeof (struct gateway));
388: if (gp == 0) {
389: fprintf(stderr, "htable: out of memory\n");
390: exit(1);
391: }
392: gp->g_link = (struct gateway *) NULL;
393: if (lastgateway)
394: lastgateway->g_link = gp;
395: else
396: gateways = gp;
397: lastgateway = gp;
398: gp->g_name = namelist;
399: gp->g_net = net;
400: gp->g_addr = addr;
401: gp->g_metric = metric;
402: if (metric == 1)
403: gp->g_dst = gp;
404: return (gp);
405: }
406:
407: connectedto(net)
408: u_long net;
409: {
410: register i;
411:
412: for (i = 0; i < nconnected; i++)
413: if (connected_nets[i] == net)
414: return(1);
415: return(0);
416: }
417:
418: local(net)
419: u_long net;
420: {
421: register i;
422:
423: for (i = 0; i < nlocal; i++)
424: if (local_nets[i] == net)
425: return(1);
426: return(0);
427: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.