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: }

Defined functions

db_load defined in line 78; used 2 times
endline defined in line 606; used 1 times
getnonblank defined in line 547; used 2 times
getnum defined in line 498; used 5 times
getprotocol defined in line 620; used 1 times
getservices defined in line 639; used 1 times
gettoken defined in line 354; used 1 times
getw_b_nl defined in line 463; used 1 times
getword defined in line 406; used 17 times
makename defined in line 578; used 5 times

Defined variables

lineno defined in line 72; used 18 times
m_class defined in line 35; used 3 times
m_type defined in line 41; used 3 times
sccsid defined in line 2; never used

Defined struct's

map defined in line 30; used 6 times

Defined macros

AT defined in line 67; used 1 times
CURRENT defined in line 65; used 1 times
DNAME defined in line 68; used 1 times
DOT defined in line 66; used 1 times
INCLUDE defined in line 69; used 1 times
MAXLEN defined in line 618; used 2 times
MAXPORT defined in line 617; used 3 times
NCLASS defined in line 39; used 1 times
NTYPE defined in line 60; used 1 times
ORIGIN defined in line 70; used 1 times
Last modified: 1986-05-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2426
Valid CSS Valid XHTML 1.0 Strict