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