|
|
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.