|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)db_load.c 4.3 (Berkeley) 5/30/86"; ! 3: #endif ! 4: ! 5: /* ! 6: * Copyright (c) 1986 Regents of the University of California ! 7: * All Rights Reserved ! 8: */ ! 9: ! 10: /* ! 11: * Load data base from ascii backupfile. Format similar to RFC 883. ! 12: */ ! 13: ! 14: #include <sys/types.h> ! 15: #include <sys/time.h> ! 16: #include <netinet/in.h> ! 17: #include <stdio.h> ! 18: #include <syslog.h> ! 19: #include <ctype.h> ! 20: #include <netdb.h> ! 21: #include <arpa/nameser.h> ! 22: #include "ns.h" ! 23: #include "db.h" ! 24: ! 25: extern char *index(); ! 26: ! 27: /* ! 28: * Map class and type names to number ! 29: */ ! 30: struct map { ! 31: char token[8]; ! 32: int val; ! 33: }; ! 34: ! 35: struct map m_class[] = { ! 36: "in", C_IN, ! 37: "any", C_ANY, ! 38: }; ! 39: #define NCLASS (sizeof(m_class)/sizeof(struct map)) ! 40: ! 41: struct map m_type[] = { ! 42: "a", T_A, ! 43: "ns", T_NS, ! 44: "cname", T_CNAME, ! 45: "soa", T_SOA, ! 46: "mb", T_MB, ! 47: "mg", T_MG, ! 48: "mr", T_MR, ! 49: "null", T_NULL, ! 50: "wks", T_WKS, ! 51: "ptr", T_PTR, ! 52: "hinfo", T_HINFO, ! 53: "minfo", T_MINFO, ! 54: "mx", T_MX, ! 55: "uinfo", T_UINFO, ! 56: "uid", T_UID, ! 57: "gid", T_GID, ! 58: "any", T_ANY, ! 59: }; ! 60: #define NTYPE (sizeof(m_type)/sizeof(struct map)) ! 61: ! 62: /* ! 63: * Parser token values ! 64: */ ! 65: #define CURRENT 1 ! 66: #define DOT 2 ! 67: #define AT 3 ! 68: #define DNAME 4 ! 69: #define INCLUDE 5 ! 70: #define ORIGIN 6 ! 71: ! 72: int lineno = 1; /* current line number */ ! 73: ! 74: /* ! 75: * Load the database from 'filename'. Origin is appended to all domain ! 76: * names in the file. ! 77: */ ! 78: db_load(filename, in_origin, zone) ! 79: char *filename, *in_origin; ! 80: int zone; ! 81: { ! 82: register char *cp; ! 83: register struct map *mp; ! 84: char domain[MAXDNAME]; ! 85: char origin[MAXDNAME]; ! 86: char buf[BUFSIZ]; ! 87: char data[MAXDATA]; ! 88: char *op; ! 89: int class, type, ttl; ! 90: struct databuf *dp; ! 91: FILE *fp; ! 92: int slineno, i; ! 93: long n; ! 94: ! 95: #ifdef DEBUG ! 96: if (debug) ! 97: fprintf(ddt,"db_load(%s, %s, %d)\n", filename, in_origin, zone); ! 98: #endif ! 99: ! 100: (void) strcpy(origin, in_origin); ! 101: if ((fp = fopen(filename, "r")) == NULL) { ! 102: syslog(LOG_ERR, "%s: %m", filename); ! 103: return (NODBFILE); ! 104: } ! 105: lineno = 1; ! 106: domain[0] = '\0'; ! 107: class = C_IN; ! 108: while ((n = gettoken(fp)) != EOF) { ! 109: switch ((int)n) { ! 110: case INCLUDE: ! 111: if (!getword(buf, sizeof(buf), fp)) /* file name */ ! 112: break; ! 113: slineno = lineno; ! 114: (void) db_load(buf, origin, zone); ! 115: lineno = slineno; ! 116: continue; ! 117: ! 118: case ORIGIN: ! 119: (void) strcpy(buf, origin); ! 120: if (!getword(origin, sizeof(origin), fp)) ! 121: break; ! 122: makename(origin, buf); ! 123: continue; ! 124: ! 125: case DNAME: ! 126: if (!getword(domain, sizeof(domain), fp)) ! 127: break; ! 128: n = strlen(domain) - 1; ! 129: if (domain[n] == '.') ! 130: domain[n] = '\0'; ! 131: else if (*origin) { ! 132: (void) strcat(domain, "."); ! 133: (void) strcat(domain, origin); ! 134: } ! 135: goto gotdomain; ! 136: ! 137: case AT: ! 138: (void) strcpy(domain, origin); ! 139: goto gotdomain; ! 140: ! 141: case DOT: ! 142: domain[0] = '\0'; ! 143: /* fall thru ... */ ! 144: case CURRENT: ! 145: gotdomain: ! 146: if (!getword(buf, sizeof(buf), fp)) ! 147: break; ! 148: cp = buf; ! 149: if (isdigit(*cp)) { ! 150: n = 0; ! 151: do ! 152: n = n * 10 + (*cp++ - '0'); ! 153: while (isdigit(*cp)); ! 154: if (zone == 0) { ! 155: if (gettimeofday(&tt, ! 156: (struct timezone *)0) < 0) ! 157: syslog(LOG_ERR, ! 158: "gettimeofday failed: %m"); ! 159: n += (long) tt.tv_sec; ! 160: } ! 161: ttl = n; ! 162: if (!getword(buf, sizeof(buf), fp)) ! 163: break; ! 164: } else ! 165: ttl = 0; ! 166: for (mp = m_class; mp < m_class+NCLASS; mp++) ! 167: if (!cistrcmp(buf, mp->token)) { ! 168: class = mp->val; ! 169: (void) getword(buf, sizeof(buf), fp); ! 170: break; ! 171: } ! 172: for (mp = m_type; mp < m_type+NTYPE; mp++) ! 173: if (!cistrcmp(buf, mp->token)) { ! 174: type = mp->val; ! 175: goto fndtype; ! 176: } ! 177: #ifdef DEBUG ! 178: if (debug) ! 179: fprintf(ddt,"Unknown type: %s.\n", buf); ! 180: #endif ! 181: break; ! 182: fndtype: ! 183: if (!getword(buf, sizeof(buf), fp)) ! 184: break; ! 185: #ifdef DEBUG ! 186: if (debug >= 3) ! 187: fprintf(ddt,"d='%s',c=%d,t=%d, ttl=%d, data='%s'\n", ! 188: domain, class, type, ttl, buf); ! 189: #endif ! 190: /* ! 191: * Convert the ascii data 'buf' to the proper format ! 192: * based on the type and pack into 'data'. ! 193: */ ! 194: switch (type) { ! 195: case T_A: ! 196: n = ntohl((u_long)inet_addr((char *)buf)); ! 197: putlong((u_long)n, data); ! 198: n = sizeof(u_long); ! 199: break; ! 200: ! 201: case T_HINFO: ! 202: n = strlen(buf); ! 203: if (n > 255) { ! 204: syslog(LOG_WARNING, "CPU too large (%d)",n); ! 205: n = 255; ! 206: } ! 207: data[0] = n; ! 208: bcopy(buf, (char *)data + 1, (int)n); ! 209: n++; ! 210: if (!getword(buf, sizeof(buf), fp)) ! 211: break; ! 212: i = strlen(buf); ! 213: if (i > 255) { ! 214: syslog(LOG_WARNING, "OS too large (%d)", i); ! 215: i = 255; ! 216: } ! 217: data[n] = i; ! 218: bcopy(buf, data + n + 1, i); ! 219: n += i + 1; ! 220: break; ! 221: ! 222: case T_SOA: ! 223: case T_MINFO: ! 224: (void) strcpy(data, buf); ! 225: makename(data, origin); ! 226: cp = data + strlen(data) + 1; ! 227: if (!getword(cp, sizeof(data) - (cp - data),fp)) ! 228: break; ! 229: makename(cp, origin); ! 230: cp += strlen(cp) + 1; ! 231: if (type == T_MINFO) { ! 232: n = cp - data; ! 233: break; ! 234: } ! 235: if (getnonblank(fp) != '(') ! 236: goto err; ! 237: putlong((u_long)(zones[zone].z_serial = ! 238: getnum(fp)), cp); ! 239: cp += sizeof(u_long); ! 240: putlong((u_long)(zones[zone].z_refresh = ! 241: getnum(fp)), cp); ! 242: cp += sizeof(u_long); ! 243: putlong((u_long)(zones[zone].z_retry = ! 244: getnum(fp)), cp); ! 245: cp += sizeof(u_long); ! 246: putlong ((u_long)(zones[zone].z_expire = ! 247: getnum(fp)), cp); ! 248: cp += sizeof(u_long); ! 249: putlong ((u_long)(zones[zone].z_minimum = ! 250: getnum(fp)), cp); ! 251: cp += sizeof(u_long); ! 252: n = cp - data; ! 253: if (getnonblank(fp) != ')') ! 254: goto err; ! 255: endline(fp); ! 256: break; ! 257: ! 258: case T_UID: ! 259: case T_GID: ! 260: n = 0; ! 261: cp = buf; ! 262: while (isdigit(*cp)) ! 263: n = n * 10 + (*cp++ - '0'); ! 264: if (cp == buf) ! 265: goto err; ! 266: putlong((u_long)n, data); ! 267: n = sizeof(long); ! 268: break; ! 269: ! 270: case T_WKS: ! 271: /* Address */ ! 272: n = ntohl((u_long)inet_addr((char *)buf)); ! 273: putlong((u_long)n, data); ! 274: data[sizeof(u_long)] = getprotocol(fp); ! 275: /* Protocol */ ! 276: n = sizeof(u_long) + sizeof(char); ! 277: /* Services */ ! 278: n = getservices((int)n, data, fp); ! 279: break; ! 280: ! 281: case T_NS: ! 282: case T_CNAME: ! 283: case T_MB: ! 284: case T_MG: ! 285: case T_MR: ! 286: case T_PTR: ! 287: (void) strcpy(data, buf); ! 288: makename(data, origin); ! 289: n = strlen(data) + 1; ! 290: break; ! 291: ! 292: case T_UINFO: ! 293: cp = index(buf, '&'); ! 294: bzero(data, sizeof(data)); ! 295: if ( cp != NULL) { ! 296: (void) strncpy(data, buf, cp - buf); ! 297: op = index(domain, '.'); ! 298: if ( op != NULL) ! 299: (void) strncat(data, ! 300: domain,op-domain); ! 301: else ! 302: (void) strcat(data, domain); ! 303: (void) strcat(data, ++cp); ! 304: } else ! 305: (void) strcpy(data, buf); ! 306: n = strlen(data) + 1; ! 307: break; ! 308: case T_MX: ! 309: n = 0; ! 310: cp = buf; ! 311: while (isdigit(*cp)) ! 312: n = n * 10 + (*cp++ - '0'); ! 313: /* catch bad values */ ! 314: if ((cp == buf) || (n & ~0xffff)) ! 315: goto err; ! 316: ! 317: putshort((u_short)n, data); ! 318: cp = data + sizeof(u_short); ! 319: ! 320: if (!getword(buf, sizeof(buf), fp)) ! 321: break; ! 322: (void) strcpy(cp,buf); ! 323: makename(cp, origin); ! 324: /* get pointer to place in data */ ! 325: cp += strlen(cp) +1; ! 326: ! 327: /* now save length */ ! 328: n = (cp - data); ! 329: break; ! 330: ! 331: default: ! 332: goto err; ! 333: } ! 334: dp = savedata(class, type, (u_long)ttl, data, (int)n); ! 335: dp->d_zone = zone; ! 336: if ((n = db_update(domain, dp, dp, DB_NODATA)) < 0) { ! 337: #ifdef DEBUG ! 338: if (debug && (n != DATAEXISTS)) ! 339: fprintf(ddt,"update failed\n"); ! 340: #endif ! 341: } ! 342: continue; ! 343: } ! 344: err: ! 345: syslog(LOG_ERR, "%s: line %d: database format error (%s)", ! 346: filename, lineno, buf); ! 347: (void) fclose(fp); ! 348: return (-1); ! 349: } ! 350: (void) fclose(fp); ! 351: return (OK); ! 352: } ! 353: ! 354: int gettoken(fp) ! 355: register FILE *fp; ! 356: { ! 357: register int c; ! 358: char op[32]; ! 359: ! 360: for (;;) { ! 361: c = getc(fp); ! 362: top: ! 363: switch (c) { ! 364: case EOF: ! 365: return (EOF); ! 366: ! 367: case '$': ! 368: if (!getword(op, sizeof(op), fp)) ! 369: return (EOF); ! 370: if (!cistrcmp("include", op)) ! 371: return (INCLUDE); ! 372: if (!cistrcmp("origin", op)) ! 373: return (ORIGIN); ! 374: printf("Unknown $ option: %s\n", op); ! 375: /* fall through... */ ! 376: ! 377: case ';': ! 378: while ((c = getc(fp)) != EOF && c != '\n') ! 379: ; ! 380: goto top; ! 381: ! 382: case ' ': ! 383: case '\t': ! 384: return (CURRENT); ! 385: ! 386: case '.': ! 387: return (DOT); ! 388: ! 389: case '@': ! 390: return (AT); ! 391: ! 392: case '\n': ! 393: lineno++; ! 394: continue; ! 395: ! 396: default: ! 397: (void) ungetc(c, fp); ! 398: return (DNAME); ! 399: } ! 400: } ! 401: } ! 402: ! 403: /* ! 404: * Get next word, skipping blanks & comments. ! 405: */ ! 406: getword(buf, size, fp) ! 407: char *buf; ! 408: int size; ! 409: FILE *fp; ! 410: { ! 411: register char *cp; ! 412: register int c; ! 413: ! 414: for (cp = buf; (c = getc(fp)) != EOF; ) { ! 415: if (isspace(c)) { ! 416: if (c == '\n') ! 417: lineno++; ! 418: if (cp != buf) ! 419: break; ! 420: continue; ! 421: } ! 422: if (c == ';') { ! 423: while ((c = getc(fp)) != EOF && c != '\n') ! 424: ; ! 425: if (c == '\n') ! 426: lineno++; ! 427: if (cp != buf) ! 428: break; ! 429: continue; ! 430: } ! 431: if (c == '"') { ! 432: while ((c = getc(fp)) != EOF && c != '"' && c != '\n') { ! 433: if (c == '\\') { ! 434: if ((c = getc(fp)) == EOF) ! 435: c = '\\'; ! 436: if (c == '\n') ! 437: lineno++; ! 438: } ! 439: if (cp >= buf+size-1) ! 440: break; ! 441: *cp++ = c; ! 442: } ! 443: if (c == '\n') { ! 444: lineno++; ! 445: break; ! 446: } ! 447: continue; ! 448: } ! 449: if (c == '\\') { ! 450: if ((c = getc(fp)) == EOF) ! 451: c = '\\'; ! 452: if (c == '\n') ! 453: lineno++; ! 454: } ! 455: if (cp >= buf+size-1) ! 456: break; ! 457: *cp++ = c; ! 458: } ! 459: *cp = '\0'; ! 460: return (cp != buf); ! 461: } ! 462: ! 463: getw_b_nl(buf, size, fp) ! 464: char *buf; ! 465: int size; ! 466: FILE *fp; ! 467: { ! 468: register char *cp; ! 469: register int c; ! 470: ! 471: for (cp = buf; (c = getc(fp)) != EOF; ) { ! 472: if (isspace(c)) { ! 473: if (c == '\n') { ! 474: *cp = '\0'; ! 475: return (0); ! 476: } ! 477: if (cp != buf) ! 478: break; ! 479: continue; ! 480: } ! 481: if (c == ';') { ! 482: while ((c = getc(fp)) != EOF && c != '\n') ! 483: ; ! 484: if (c == '\n') ! 485: lineno++; ! 486: if (cp != buf) ! 487: break; ! 488: continue; ! 489: } ! 490: if (cp >= buf+size-1) ! 491: break; ! 492: *cp++ = c; ! 493: } ! 494: *cp = '\0'; ! 495: return (cp != buf); ! 496: } ! 497: ! 498: getnum(fp) ! 499: FILE *fp; ! 500: { ! 501: register int c, n; ! 502: int seendigit = 0; ! 503: int seendecimal = 0; ! 504: ! 505: for (n = 0; (c = getc(fp)) != EOF; ) { ! 506: if (isspace(c)) { ! 507: if (c == '\n') ! 508: lineno++; ! 509: if (seendigit) ! 510: break; ! 511: continue; ! 512: } ! 513: if (c == ';') { ! 514: while ((c = getc(fp)) != EOF && c != '\n') ! 515: ; ! 516: if (c == '\n') ! 517: lineno++; ! 518: if (seendigit) ! 519: break; ! 520: continue; ! 521: } ! 522: if (!isdigit(c)) { ! 523: if (c != '.') { ! 524: syslog(LOG_ERR, "line %d: expected a number", ! 525: lineno); ! 526: exit(1); ! 527: } ! 528: if (!seendigit) ! 529: n = 1; ! 530: if (seendecimal) { ! 531: syslog(LOG_ERR, "line %d: expected a number", ! 532: lineno); ! 533: exit(1); ! 534: } else { ! 535: n = n * 1000 ; ! 536: seendigit = 1; ! 537: seendecimal = 1; ! 538: } ! 539: continue; ! 540: } ! 541: n = n * 10 + (c - '0'); ! 542: seendigit = 1; ! 543: } ! 544: return (n); ! 545: } ! 546: ! 547: getnonblank(fp) ! 548: FILE *fp; ! 549: { ! 550: register int c; ! 551: ! 552: while ( (c = getc(fp)) != EOF ) { ! 553: if (isspace(c)) { ! 554: if (c == '\n') ! 555: lineno++; ! 556: continue; ! 557: } ! 558: if (c == ';') { ! 559: while ((c = getc(fp)) != EOF && c != '\n') ! 560: ; ! 561: if (c == '\n') ! 562: lineno++; ! 563: continue; ! 564: } ! 565: return(c); ! 566: } ! 567: syslog(LOG_ERR, "line %d: unexpected EOF", lineno); ! 568: return (EOF); ! 569: } ! 570: ! 571: /* ! 572: * Take name and fix it according to following rules: ! 573: * "." means root. ! 574: * "@" means current origin. ! 575: * "name." means no changes. ! 576: * "name" means append origin. ! 577: */ ! 578: makename(name, origin) ! 579: char *name, *origin; ! 580: { ! 581: int n; ! 582: ! 583: if (origin[0] == '.') ! 584: origin++; ! 585: n = strlen(name); ! 586: if (n == 1) { ! 587: if (name[0] == '.') { ! 588: name[0] = '\0'; ! 589: return; ! 590: } ! 591: if (name[0] == '@') { ! 592: (void) strcpy(name, origin); ! 593: return; ! 594: } ! 595: } ! 596: if (n > 0) { ! 597: if (name[n - 1] == '.') ! 598: name[n - 1] = '\0'; ! 599: else if (origin[0] != '\0') { ! 600: name[n] = '.'; ! 601: (void) strcpy(name + n + 1, origin); ! 602: } ! 603: } ! 604: } ! 605: ! 606: endline(fp) ! 607: register FILE *fp; ! 608: { ! 609: register int c; ! 610: while (c = getc(fp)) ! 611: if ((c == EOF) || (c == '\n')) { ! 612: (void) ungetc(c,fp); ! 613: break; ! 614: } ! 615: } ! 616: ! 617: #define MAXPORT 256 ! 618: #define MAXLEN 24 ! 619: ! 620: getprotocol(fp) ! 621: FILE *fp; ! 622: { ! 623: int k; ! 624: char b[MAXLEN]; ! 625: struct protoent *proto; ! 626: ! 627: (void) getword(b, sizeof(b), fp); ! 628: ! 629: proto = getprotobyname(b); ! 630: if(proto == NULL) { ! 631: k = 0; ! 632: (void) sscanf(b,"%d",&k); ! 633: } ! 634: else ! 635: k = proto->p_proto; ! 636: return(k); ! 637: } ! 638: ! 639: int getservices(n, data, fp) ! 640: int n; ! 641: char *data; ! 642: FILE *fp; ! 643: { ! 644: int j, ch; ! 645: u_short k; ! 646: int maxl; ! 647: int bracket, eol; ! 648: char b[MAXLEN]; ! 649: char bm[MAXPORT/8]; ! 650: struct servent *service; ! 651: ! 652: for (j = 0; j < MAXPORT/8; j++) ! 653: bm[j] = 0; ! 654: maxl = 0; ! 655: bracket = eol = 0; ! 656: while (1) { ! 657: if (!getw_b_nl(b, sizeof(b), fp) && (!bracket)) { ! 658: if (strlen(b) == 0) ! 659: break; ! 660: eol++; ! 661: } ! 662: if ( b[0] == '(') { ! 663: bracket++; ! 664: continue; ! 665: } ! 666: if ( b[0] == ')') { ! 667: bracket = 0; ! 668: while ((ch = getc(fp)) != EOF && ch != '\n') ! 669: ; ! 670: break; ! 671: } ! 672: service = getservbyname(b, (char *)NULL); ! 673: if (service == NULL) { ! 674: k=0; ! 675: (void) sscanf(b,"%d",&k); ! 676: if (k == 0) ! 677: continue; ! 678: } ! 679: else ! 680: k = ntohs((u_short)service->s_port); ! 681: if ((k < MAXPORT) && (k)) { ! 682: bm[k/8] |= (0x80>>(k%8)); ! 683: if (k > maxl) ! 684: maxl=k; ! 685: } ! 686: else ! 687: syslog(LOG_WARNING,"port no.(%d) too big\n",k); ! 688: if(eol) ! 689: break; ! 690: } ! 691: maxl = maxl/8+1; ! 692: bcopy(bm, data+n, maxl); ! 693: return(maxl+n); ! 694: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.