|
|
1.1 root 1: /*
2: * Copyright (c) 1986, 1988, 1990 Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #ifndef lint
21: static char sccsid[] = "@(#)db_load.c 4.37 (Berkeley) 6/1/90";
22: #endif /* not lint */
23:
24: /*
25: * Load data base from ascii backupfile. Format similar to RFC 883.
26: */
27:
28: #include <sys/param.h>
29: #include <sys/time.h>
30: #include <sys/stat.h>
31: #include <netinet/in.h>
32: #include <stdio.h>
33: #include <syslog.h>
34: #include <ctype.h>
35: #include <netdb.h>
36: #include <arpa/nameser.h>
37: #include "ns.h"
38: #include "db.h"
39:
40: extern char *index();
41: extern int max_cache_ttl;
42:
43: /*
44: * Map class and type names to number
45: */
46: struct map {
47: char token[8];
48: int val;
49: };
50:
51: struct map m_class[] = {
52: "in", C_IN,
53: #ifdef notdef
54: "any", C_ANY, /* any is a QCLASS, not CLASS */
55: #endif
56: "chaos", C_CHAOS,
57: "hs", C_HS,
58: };
59: #define NCLASS (sizeof(m_class)/sizeof(struct map))
60:
61: struct map m_type[] = {
62: "a", T_A,
63: "ns", T_NS,
64: "cname", T_CNAME,
65: "soa", T_SOA,
66: "mb", T_MB,
67: "mg", T_MG,
68: "mr", T_MR,
69: "null", T_NULL,
70: "wks", T_WKS,
71: "ptr", T_PTR,
72: "hinfo", T_HINFO,
73: "minfo", T_MINFO,
74: "mx", T_MX,
75: "uinfo", T_UINFO,
76: "txt", T_TXT,
77: "uid", T_UID,
78: "gid", T_GID,
79: #ifdef notdef
80: "any", T_ANY, /* any is a QTYPE, not TYPE */
81: #endif
82: #ifdef ALLOW_T_UNSPEC
83: "unspec", T_UNSPEC,
84: #endif ALLOW_T_UNSPEC
85: };
86: #define NTYPE (sizeof(m_type)/sizeof(struct map))
87:
88: /*
89: * Parser token values
90: */
91: #define CURRENT 1
92: #define DOT 2
93: #define AT 3
94: #define DNAME 4
95: #define INCLUDE 5
96: #define ORIGIN 6
97: #define ERROR 7
98:
99: int lineno; /* current line number */
100:
101: /*
102: * Load the database from 'filename'. Origin is appended to all domain
103: * names in the file.
104: */
105: db_load(filename, in_origin, zp, doinginclude)
106: char *filename, *in_origin;
107: struct zoneinfo *zp;
108: {
109: register u_char *cp;
110: register struct map *mp;
111: char domain[MAXDNAME];
112: char origin[MAXDNAME];
113: char tmporigin[MAXDNAME];
114: u_char buf[MAXDATA];
115: u_char data[MAXDATA];
116: u_char *cp1;
117: char *op;
118: int c;
119: int class, type, ttl, dbflags, dataflags;
120: int read_soa = 0; /* number of soa's read */
121: struct databuf *dp;
122: FILE *fp;
123: int slineno, i, errs = 0, didinclude = 0;
124: register u_long n;
125: struct stat sb;
126:
127: #ifdef DEBUG
128: if (debug)
129: fprintf(ddt,"db_load(%s, %s, %d, %d)\n",
130: filename, in_origin, zp - zones, doinginclude);
131: #endif
132:
133: (void) strcpy(origin, in_origin);
134: if ((fp = fopen(filename, "r")) == NULL) {
135: syslog(LOG_ERR, "%s: %m", filename);
136: #ifdef DEBUG
137: if (debug)
138: fprintf(ddt,"db_load: error opening file %s\n", filename);
139: #endif
140: return (-1);
141: }
142: if (zp->z_type == Z_CACHE) {
143: dbflags = DB_NODATA | DB_NOHINTS;
144: dataflags = DB_F_HINT;
145: } else {
146: dbflags = DB_NODATA;
147: dataflags = 0;
148: }
149: gettime(&tt);
150: if (fstat(fileno(fp), &sb) < 0) {
151: syslog(LOG_ERR, "%s: %m", filename);
152: sb.st_mtime = (int)tt.tv_sec;
153: }
154: slineno = lineno;
155: lineno = 1;
156: domain[0] = '\0';
157: class = C_IN;
158: zp->z_state &= ~(Z_INCLUDE|Z_DB_BAD);
159: while ((c = gettoken(fp)) != EOF) {
160: switch (c) {
161: case INCLUDE:
162: if (!getword(buf, sizeof(buf), fp)) /* file name */
163: break;
164: if (!getword(tmporigin, sizeof(tmporigin), fp))
165: strcpy(tmporigin, origin);
166: else {
167: makename(tmporigin, origin);
168: endline(fp);
169: }
170: didinclude = 1;
171: errs += db_load(buf, tmporigin, zp, 1);
172: continue;
173:
174: case ORIGIN:
175: (void) strcpy(buf, origin);
176: if (!getword(origin, sizeof(origin), fp))
177: break;
178: #ifdef DEBUG
179: if (debug > 3)
180: fprintf(ddt,"db_load: origin %s, buf %s\n",
181: origin, buf);
182: #endif
183: makename(origin, buf);
184: #ifdef DEBUG
185: if (debug > 3)
186: fprintf(ddt,"db_load: origin now %s\n", origin);
187: #endif
188: continue;
189:
190: case DNAME:
191: if (!getword(domain, sizeof(domain), fp))
192: break;
193: n = strlen(domain) - 1;
194: if (domain[n] == '.')
195: domain[n] = '\0';
196: else if (*origin) {
197: (void) strcat(domain, ".");
198: (void) strcat(domain, origin);
199: }
200: goto gotdomain;
201:
202: case AT:
203: (void) strcpy(domain, origin);
204: goto gotdomain;
205:
206: case DOT:
207: domain[0] = '\0';
208: /* fall thru ... */
209: case CURRENT:
210: gotdomain:
211: if (!getword(buf, sizeof(buf), fp)) {
212: if (c == CURRENT)
213: continue;
214: break;
215: }
216: cp = buf;
217: ttl = 0;
218: if (isdigit(*cp)) {
219: n = 0;
220: do
221: n = n * 10 + (*cp++ - '0');
222: while (isdigit(*cp));
223: if (zp->z_type == Z_CACHE) {
224: /* this allows the cache entry to age */
225: /* while sitting on disk (powered off) */
226: if (n > max_cache_ttl)
227: n = max_cache_ttl;
228: n += sb.st_mtime;
229: }
230: ttl = n;
231: if (!getword(buf, sizeof(buf), fp))
232: break;
233: }
234: for (mp = m_class; mp < m_class+NCLASS; mp++)
235: if (!strcasecmp(buf, mp->token)) {
236: class = mp->val;
237: (void) getword(buf, sizeof(buf), fp);
238: break;
239: }
240: for (mp = m_type; mp < m_type+NTYPE; mp++)
241: if (!strcasecmp(buf, mp->token)) {
242: type = mp->val;
243: goto fndtype;
244: }
245: #ifdef DEBUG
246: if (debug)
247: fprintf(ddt,"Line %d: Unknown type: %s.\n",
248: lineno, buf);
249: #endif
250: errs++;
251: syslog(LOG_ERR, "Line %d: Unknown type: %s.\n",
252: lineno, buf);
253: break;
254: fndtype:
255: #ifdef ALLOW_T_UNSPEC
256: /* Don't do anything here for T_UNSPEC...
257: * read input separately later
258: */
259: if (type != T_UNSPEC) {
260: #endif ALLOW_T_UNSPEC
261: if (!getword(buf, sizeof(buf), fp))
262: break;
263: #ifdef DEBUG
264: if (debug >= 3)
265: fprintf(ddt,
266: "d='%s', c=%d, t=%d, ttl=%d, data='%s'\n",
267: domain, class, type, ttl, buf);
268: #endif
269: #ifdef ALLOW_T_UNSPEC
270: }
271: #endif ALLOW_T_UNSPEC
272: /*
273: * Convert the ascii data 'buf' to the proper format
274: * based on the type and pack into 'data'.
275: */
276: switch (type) {
277: case T_A:
278: n = ntohl((u_long)inet_addr((char *)buf));
279: cp = data;
280: PUTLONG(n, cp);
281: n = sizeof(u_long);
282: break;
283:
284: case T_HINFO:
285: n = strlen(buf);
286: if (n > 255) {
287: syslog(LOG_WARNING,
288: "%s: line %d: CPU type too long",
289: filename, lineno);
290: n = 255;
291: }
292: data[0] = n;
293: bcopy(buf, (char *)data + 1, (int)n);
294: n++;
295: if (!getword(buf, sizeof(buf), fp))
296: break;
297: i = strlen(buf);
298: if (i > 255) {
299: syslog(LOG_WARNING,
300: "%s: line %d: OS type too long",
301: filename, lineno);
302: i = 255;
303: }
304: data[n] = i;
305: bcopy(buf, data + n + 1, i);
306: n += i + 1;
307: endline(fp);
308: break;
309:
310: case T_SOA:
311: case T_MINFO:
312: (void) strcpy(data, buf);
313: makename(data, origin);
314: cp = data + strlen(data) + 1;
315: if (!getword(cp, sizeof(data) - (cp - data),fp)) {
316: n = cp - data;
317: break;
318: }
319: makename(cp, origin);
320: cp += strlen(cp) + 1;
321: if (type == T_MINFO) {
322: n = cp - data;
323: break;
324: }
325: if (getnonblank(fp) != '(')
326: goto err;
327: zp->z_serial = getnum(fp);
328: n = (u_long) zp->z_serial;
329: PUTLONG(n, cp);
330: zp->z_refresh = getnum(fp);
331: n = (u_long) zp->z_refresh;
332: PUTLONG(n, cp);
333: if (zp->z_type == Z_SECONDARY)
334: zp->z_time = sb.st_mtime + zp->z_refresh;
335: zp->z_retry = getnum(fp);
336: n = (u_long) zp->z_retry;
337: PUTLONG(n, cp);
338: zp->z_expire = getnum(fp);
339: n = (u_long) zp->z_expire;
340: PUTLONG (n, cp);
341: zp->z_minimum = getnum(fp);
342: n = (u_long) zp->z_minimum;
343: PUTLONG (n, cp);
344: n = cp - data;
345: if (getnonblank(fp) != ')')
346: goto err;
347: read_soa++;
348: endline(fp);
349: break;
350:
351: case T_UID:
352: case T_GID:
353: n = 0;
354: cp = buf;
355: while (isdigit(*cp))
356: n = n * 10 + (*cp++ - '0');
357: if (cp == buf)
358: goto err;
359: cp = data;
360: PUTLONG(n, cp);
361: n = sizeof(long);
362: break;
363:
364: case T_WKS:
365: /* Address */
366: n = ntohl((u_long)inet_addr((char *)buf));
367: cp = data;
368: PUTLONG(n, cp);
369: *cp = getprotocol(fp, filename);
370: /* Protocol */
371: n = sizeof(u_long) + sizeof(char);
372: /* Services */
373: n = getservices((int)n, data, fp, filename);
374: break;
375:
376: case T_NS:
377: case T_CNAME:
378: case T_MB:
379: case T_MG:
380: case T_MR:
381: case T_PTR:
382: (void) strcpy(data, buf);
383: makename(data, origin);
384: n = strlen(data) + 1;
385: break;
386:
387: case T_UINFO:
388: cp = (u_char *)index(buf, '&');
389: bzero(data, sizeof(data));
390: if ( cp != NULL) {
391: (void) strncpy(data, buf, cp - buf);
392: op = index(domain, '.');
393: if ( op != NULL)
394: (void) strncat(data,
395: domain,op-domain);
396: else
397: (void) strcat(data, domain);
398: (void) strcat(data, ++cp);
399: } else
400: (void) strcpy(data, buf);
401: n = strlen(data) + 1;
402: break;
403: case T_MX:
404: n = 0;
405: cp = buf;
406: while (isdigit(*cp))
407: n = n * 10 + (*cp++ - '0');
408: /* catch bad values */
409: if ((cp == buf) || (n > 65535))
410: goto err;
411:
412: cp = data;
413: PUTSHORT((u_short)n, cp);
414:
415: if (!getword(buf, sizeof(buf), fp))
416: break;
417: (void) strcpy(cp,buf);
418: makename(cp, origin);
419: /* get pointer to place in data */
420: cp += strlen(cp) +1;
421:
422: /* now save length */
423: n = (cp - data);
424: break;
425:
426: case T_TXT:
427: i = strlen(buf);
428: cp = data;
429: cp1 = buf;
430: /*
431: * there is expansion here so make sure we
432: * don't overflow data
433: */
434: if (i > sizeof(data) * 255 / 256) {
435: syslog(LOG_WARNING,
436: "%s: line %d: TXT record truncated",
437: filename, lineno);
438: i = sizeof(data) * 255 / 256;
439: }
440: while (i > 255) {
441: *cp++ = 255;
442: bcopy(cp1, cp, 255);
443: cp += 255;
444: cp1 += 255;
445: i -= 255;
446: }
447: *cp++ = i;
448: bcopy(cp1, cp, i);
449: cp += i;
450: n = cp - data;
451: endline(fp);
452: break;
453: #ifdef ALLOW_T_UNSPEC
454: case T_UNSPEC:
455: {
456: int rcode;
457: fgets(buf, sizeof(buf), fp);
458: #ifdef DEBUG
459: if (debug)
460: fprintf(ddt, "loading T_UNSPEC\n");
461: #endif DEBUG
462: if (rcode = atob(buf, strlen(buf), data,
463: sizeof(data), &n)) {
464: if (rcode == CONV_OVERFLOW) {
465: #ifdef DEBUG
466: if (debug)
467: fprintf(ddt,
468: "Load T_UNSPEC: input buffer overflow\n");
469: #endif DEBUG
470: errs++;
471: syslog(LOG_ERR,
472: "Load T_UNSPEC: input buffer overflow");
473: } else {
474: #ifdef DEBUG
475: if (debug)
476: fprintf(ddt,
477: "Load T_UNSPEC: Data in bad atob format\n");
478: #endif DEBUG
479: errs++;
480: syslog(LOG_ERR,
481: "Load T_UNSPEC: Data in bad atob format");
482: }
483: }
484: }
485: break;
486: #endif ALLOW_T_UNSPEC
487:
488: default:
489: goto err;
490: }
491: dp = savedata(class, type, (u_long)ttl, data, (int)n);
492: dp->d_zone = zp - zones;
493: dp->d_flags = dataflags;
494: if ((c = db_update(domain, dp, dp, dbflags,
495: (zp->z_type == Z_CACHE)? fcachetab : hashtab)) < 0) {
496: #ifdef DEBUG
497: if (debug && (c != DATAEXISTS))
498: fprintf(ddt,"update failed\n");
499: #endif
500: }
501: continue;
502:
503: case ERROR:
504: break;
505: }
506: err:
507: errs++;
508: syslog(LOG_ERR, "%s: line %d: database format error (%s)",
509: filename, lineno, buf);
510: #ifdef DEBUG
511: if (debug)
512: fprintf(ddt,"%s: line %d: database format error ('%s', %d)\n",
513: filename, lineno, buf, n);
514: #endif
515: while ((c = getc(fp)) != EOF && c != '\n')
516: ;
517: if (c == '\n')
518: lineno++;
519: }
520: (void) fclose(fp);
521: lineno = slineno;
522: if (doinginclude == 0) {
523: if (didinclude) {
524: zp->z_state |= Z_INCLUDE;
525: zp->z_ftime = 0;
526: } else
527: zp->z_ftime = sb.st_mtime;
528: zp->z_lastupdate = sb.st_mtime;
529: if (zp->z_type != Z_CACHE && read_soa != 1) {
530: errs++;
531: if (read_soa == 0)
532: syslog(LOG_ERR, "%s: no SOA record", filename);
533: else
534: syslog(LOG_ERR, "%s: multiple SOA records",
535: filename);
536: }
537: }
538: if (errs)
539: zp->z_state |= Z_DB_BAD;
540: return (errs);
541: }
542:
543: int gettoken(fp)
544: register FILE *fp;
545: {
546: register int c;
547: char op[32];
548:
549: for (;;) {
550: c = getc(fp);
551: top:
552: switch (c) {
553: case EOF:
554: return (EOF);
555:
556: case '$':
557: if (getword(op, sizeof(op), fp)) {
558: if (!strcasecmp("include", op))
559: return (INCLUDE);
560: if (!strcasecmp("origin", op))
561: return (ORIGIN);
562: }
563: #ifdef DEBUG
564: if (debug)
565: fprintf(ddt,"Line %d: Unknown $ option: $%s\n",
566: lineno, op);
567: #endif
568: syslog(LOG_ERR,"Line %d: Unknown $ option: $%s\n",
569: lineno, op);
570: return (ERROR);
571:
572: case ';':
573: while ((c = getc(fp)) != EOF && c != '\n')
574: ;
575: goto top;
576:
577: case ' ':
578: case '\t':
579: return (CURRENT);
580:
581: case '.':
582: return (DOT);
583:
584: case '@':
585: return (AT);
586:
587: case '\n':
588: lineno++;
589: continue;
590:
591: default:
592: (void) ungetc(c, fp);
593: return (DNAME);
594: }
595: }
596: }
597:
598: /*
599: * Get next word, skipping blanks & comments.
600: */
601: getword(buf, size, fp)
602: char *buf;
603: int size;
604: FILE *fp;
605: {
606: register char *cp;
607: register int c;
608:
609: for (cp = buf; (c = getc(fp)) != EOF; ) {
610: if (c == ';') {
611: while ((c = getc(fp)) != EOF && c != '\n')
612: ;
613: c = '\n';
614: }
615: if (c == '\n') {
616: if (cp != buf)
617: ungetc(c, fp);
618: else
619: lineno++;
620: break;
621: }
622: if (isspace(c)) {
623: while (isspace(c = getc(fp)) && c != '\n')
624: ;
625: ungetc(c, fp);
626: if (cp != buf) /* Trailing whitespace */
627: break;
628: continue; /* Leading whitespace */
629: }
630: if (c == '"') {
631: while ((c = getc(fp)) != EOF && c != '"' && c != '\n') {
632: if (c == '\\') {
633: if ((c = getc(fp)) == EOF)
634: c = '\\';
635: if (c == '\n')
636: lineno++;
637: }
638: if (cp >= buf+size-1)
639: break;
640: *cp++ = c;
641: }
642: if (c == '\n') {
643: lineno++;
644: break;
645: }
646: continue;
647: }
648: if (c == '\\') {
649: if ((c = getc(fp)) == EOF)
650: c = '\\';
651: if (c == '\n')
652: lineno++;
653: }
654: if (cp >= buf+size-1)
655: break;
656: *cp++ = c;
657: }
658: *cp = '\0';
659: return (cp != buf);
660: }
661:
662: getnum(fp)
663: FILE *fp;
664: {
665: register int c, n;
666: int seendigit = 0;
667: int seendecimal = 0;
668:
669: for (n = 0; (c = getc(fp)) != EOF; ) {
670: if (isspace(c)) {
671: if (c == '\n')
672: lineno++;
673: if (seendigit)
674: break;
675: continue;
676: }
677: if (c == ';') {
678: while ((c = getc(fp)) != EOF && c != '\n')
679: ;
680: if (c == '\n')
681: lineno++;
682: if (seendigit)
683: break;
684: continue;
685: }
686: if (!isdigit(c)) {
687: if (c == ')' && seendigit) {
688: (void) ungetc(c, fp);
689: break;
690: }
691: if (seendecimal || c != '.') {
692: syslog(LOG_ERR, "line %d: expected a number",
693: lineno);
694: #ifdef DEBUG
695: if (debug)
696: fprintf(ddt,"line %d: expected a number",
697: lineno);
698: #endif
699: exit(1); /* XXX why exit */
700: } else {
701: if (!seendigit)
702: n = 1;
703: n = n * 1000 ;
704: seendigit = 1;
705: seendecimal = 1;
706: }
707: continue;
708: }
709: n = n * 10 + (c - '0');
710: seendigit = 1;
711: }
712: return (n);
713: }
714:
715: getnonblank(fp)
716: FILE *fp;
717: {
718: register int c;
719:
720: while ( (c = getc(fp)) != EOF ) {
721: if (isspace(c)) {
722: if (c == '\n')
723: lineno++;
724: continue;
725: }
726: if (c == ';') {
727: while ((c = getc(fp)) != EOF && c != '\n')
728: ;
729: if (c == '\n')
730: lineno++;
731: continue;
732: }
733: return(c);
734: }
735: syslog(LOG_ERR, "line %d: unexpected EOF", lineno);
736: #ifdef DEBUG
737: if (debug)
738: fprintf(ddt, "line %d: unexpected EOF", lineno);
739: #endif
740: return (EOF);
741: }
742:
743: /*
744: * Take name and fix it according to following rules:
745: * "." means root.
746: * "@" means current origin.
747: * "name." means no changes.
748: * "name" means append origin.
749: */
750: makename(name, origin)
751: char *name, *origin;
752: {
753: int n;
754:
755: if (origin[0] == '.')
756: origin++;
757: n = strlen(name);
758: if (n == 1) {
759: if (name[0] == '.') {
760: name[0] = '\0';
761: return;
762: }
763: if (name[0] == '@') {
764: (void) strcpy(name, origin);
765: return;
766: }
767: }
768: if (n > 0) {
769: if (name[n - 1] == '.')
770: name[n - 1] = '\0';
771: else if (origin[0] != '\0') {
772: name[n] = '.';
773: (void) strcpy(name + n + 1, origin);
774: }
775: }
776: }
777:
778: endline(fp)
779: register FILE *fp;
780: {
781: register int c;
782: while (c = getc(fp))
783: if (c == '\n') {
784: (void) ungetc(c,fp);
785: break;
786: } else if (c == EOF)
787: break;
788: }
789:
790: #define MAXPORT 256
791: #define MAXLEN 24
792:
793: getprotocol(fp, src)
794: FILE *fp;
795: char *src;
796: {
797: int k;
798: char b[MAXLEN];
799:
800: (void) getword(b, sizeof(b), fp);
801:
802: k = protocolnumber(b);
803: if(k == -1)
804: syslog(LOG_ERR, "%s: line %d: unknown protocol: %s.",
805: src, lineno, b);
806: return(k);
807: }
808:
809: int
810: getservices(n, data, fp, src)
811: int n;
812: char *data, *src;
813: FILE *fp;
814: {
815: int j, ch;
816: int k;
817: int maxl;
818: int bracket;
819: char b[MAXLEN];
820: char bm[MAXPORT/8];
821:
822: for (j = 0; j < MAXPORT/8; j++)
823: bm[j] = 0;
824: maxl = 0;
825: bracket = 0;
826: while (getword(b, sizeof(b), fp) || bracket) {
827: if (feof(fp) || ferror(fp))
828: break;
829: if (strlen(b) == 0)
830: continue;
831: if ( b[0] == '(') {
832: bracket++;
833: continue;
834: }
835: if ( b[0] == ')') {
836: bracket = 0;
837: while ((ch = getc(fp)) != EOF && ch != '\n')
838: ;
839: if (ch == '\n')
840: lineno++;
841: break;
842: }
843: k = servicenumber(b);
844: if (k == -1) {
845: syslog(LOG_WARNING, "%s: line %d: Unknown service '%s'",
846: src, lineno, b);
847: continue;
848: }
849: if ((k < MAXPORT) && (k)) {
850: bm[k/8] |= (0x80>>(k%8));
851: if (k > maxl)
852: maxl=k;
853: }
854: else {
855: syslog(LOG_WARNING,
856: "%s: line %d: port no. (%d) too big\n",
857: src, lineno, k);
858: #ifdef DEBUG
859: if (debug)
860: fprintf(ddt,
861: "%s: line %d: port no. (%d) too big\n",
862: src, lineno, k);
863: #endif
864: }
865: }
866: if (bracket)
867: syslog(LOG_WARNING, "%s: line %d: missing close paren\n",
868: src, lineno);
869: maxl = maxl/8+1;
870: bcopy(bm, data+n, maxl);
871: return(maxl+n);
872: }
873:
874: get_sort_list(fp)
875: FILE *fp;
876: {
877: extern struct netinfo **enettab;
878: register struct netinfo *ntp, **end = enettab;
879: extern struct netinfo *findnetinfo();
880: struct in_addr addr;
881: char buf[BUFSIZ];
882:
883: #ifdef DEBUG
884: if (debug)
885: fprintf(ddt,"sortlist ");
886: #endif
887: while (getword(buf, sizeof(buf), fp)) {
888: if (strlen(buf) == 0)
889: break;
890: #ifdef DEBUG
891: if (debug)
892: fprintf(ddt," %s",buf);
893: #endif
894: addr.s_addr = inet_addr(buf);
895: if (addr.s_addr == (unsigned)-1) {
896: /* resolve name to address - XXX */
897: continue;
898: }
899: /* Check for duplicates, then add to linked list */
900: if (findnetinfo(addr))
901: continue;
902: ntp = (struct netinfo *)malloc(sizeof(struct netinfo));
903: ntp->my_addr = addr;
904: ntp->next = NULL;
905: ntp->mask = net_mask(ntp->my_addr);
906: ntp->net = ntp->my_addr.s_addr & ntp->mask;
907: if (ntp->net != addr.s_addr) {
908: struct in_addr tmpaddr;
909:
910: tmpaddr.s_addr = ntp->net;
911: syslog(LOG_WARNING, "sortlist: addr %s != %s", buf,
912: inet_ntoa(tmpaddr));
913: #ifdef DEBUG
914: if (debug)
915: fprintf(ddt, "\nsortlist: addr %s != %s\n", buf,
916: inet_ntoa(tmpaddr));
917: #endif
918: }
919:
920: *end = ntp;
921: end = &ntp->next;
922: }
923:
924: #ifdef DEBUG
925: if (debug)
926: fprintf(ddt,"\n");
927: if (debug > 2)
928: printnetinfo(*enettab);
929: if (debug > 4) {
930: extern struct netinfo *nettab;
931:
932: fprintf(ddt, "\nFull sort list:\n");
933: printnetinfo(nettab);
934: }
935: #endif
936: }
937:
938: free_sort_list()
939: {
940: extern struct netinfo **enettab;
941: register struct netinfo *ntp, *next;
942:
943: for (ntp = *enettab; ntp != NULL; ntp = next) {
944: next = ntp->next;
945: free((char *)ntp);
946: }
947: *enettab = NULL;
948: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.