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 this notice is preserved and that due credit is given
   7:  * to the University of California at Berkeley. The name of the University
   8:  * may not be used to endorse or promote products derived from this
   9:  * software without specific prior written permission. This software
  10:  * is provided ``as is'' without express or implied warranty.
  11:  */
  12: 
  13: #ifndef lint
  14: static char sccsid[] = "@(#)db_load.c	4.26 (Berkeley) 2/28/88";
  15: #endif /* not lint */
  16: 
  17: /*
  18:  * Load data base from ascii backupfile.  Format similar to RFC 883.
  19:  */
  20: 
  21: #include <sys/param.h>
  22: #include <sys/time.h>
  23: #include <sys/stat.h>
  24: #include <netinet/in.h>
  25: #include <stdio.h>
  26: #include <syslog.h>
  27: #include <ctype.h>
  28: #include <netdb.h>
  29: #include <arpa/nameser.h>
  30: #include "ns.h"
  31: #include "db.h"
  32: 
  33: extern char *index();
  34: u_long getnum();
  35: extern u_long net_mask();
  36: extern u_long max_cache_ttl;
  37: 
  38: /*
  39:  * Map class and type names to number
  40:  */
  41: struct map {
  42:     char    token[8];
  43:     int val;
  44: };
  45: 
  46: struct map m_class[] = {
  47:     "in",       C_IN,
  48: #ifdef notdef
  49:     "any",      C_ANY,      /* any is a QCLASS, not CLASS */
  50: #endif
  51:     "chaos",    C_CHAOS,
  52: };
  53: #define NCLASS (sizeof(m_class)/sizeof(struct map))
  54: 
  55: struct map m_type[] = {
  56:     "a",        T_A,
  57:     "ns",       T_NS,
  58:     "cname",    T_CNAME,
  59:     "soa",      T_SOA,
  60:     "mb",       T_MB,
  61:     "mg",       T_MG,
  62:     "mr",       T_MR,
  63:     "null",     T_NULL,
  64:     "wks",      T_WKS,
  65:     "ptr",      T_PTR,
  66:     "hinfo",    T_HINFO,
  67:     "minfo",    T_MINFO,
  68:     "mx",       T_MX,
  69:     "uinfo",    T_UINFO,
  70:     "uid",      T_UID,
  71:     "gid",      T_GID,
  72: #ifdef notdef
  73:     "any",      T_ANY,      /* any is a QTYPE, not TYPE */
  74: #endif
  75: #ifdef ALLOW_T_UNSPEC
  76:         "unspec",       T_UNSPEC,
  77: #endif ALLOW_T_UNSPEC
  78: };
  79: #define NTYPE (sizeof(m_type)/sizeof(struct map))
  80: 
  81: /*
  82:  * Parser token values
  83:  */
  84: #define CURRENT 1
  85: #define DOT 2
  86: #define AT  3
  87: #define DNAME   4
  88: #define INCLUDE 5
  89: #define ORIGIN  6
  90: #define ERROR   7
  91: 
  92: int lineno;     /* current line number */
  93: 
  94: struct valuelist {
  95:     struct valuelist *next, *prev;
  96:     char    *name;
  97:     char    *proto;
  98:     short   port;
  99: } *servicelist, *protolist;
 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)
 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[BUFSIZ];
 115:     u_char data[MAXDATA];
 116:     char *op;
 117:     int c;
 118:     int class, type, dbflags, dataflags;
 119:     u_long ttl;
 120:     struct databuf *dp;
 121:     FILE *fp;
 122:     int slineno, i, errs = 0, didinclude = 0;
 123:     register u_long n;
 124:     struct stat sb;
 125: 
 126: #ifdef DEBUG
 127:     if (debug)
 128:         fprintf(ddt,"db_load(%s, %s, %d)\n",
 129:             filename, in_origin, zp - zones);
 130: #endif
 131: 
 132:     (void) strcpy(origin, in_origin);
 133:     if ((fp = fopen(filename, "r")) == NULL) {
 134:         if (zp->z_type != Z_SECONDARY)
 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:     while ((c = gettoken(fp)) != EOF) {
 159:         switch (c) {
 160:         case INCLUDE:
 161:             if (!getword(buf, sizeof(buf), fp)) /* file name */
 162:                 break;
 163:             if (!getword(tmporigin, sizeof(tmporigin), fp))
 164:                 strcpy(tmporigin, origin);
 165:             else {
 166:                 makename(tmporigin, origin);
 167:                 endline(fp);
 168:             }
 169:             didinclude = 1;
 170:             errs += db_load(buf, tmporigin, zp);
 171:             continue;
 172: 
 173:         case ORIGIN:
 174:             (void) strcpy(buf, origin);
 175:             if (!getword(origin, sizeof(origin), fp))
 176:                 break;
 177: #ifdef DEBUG
 178:             if (debug > 3)
 179:                 fprintf(ddt,"db_load: origin %s, buf %s\n",
 180:                     origin, buf);
 181: #endif
 182:             makename(origin, buf);
 183: #ifdef DEBUG
 184:             if (debug > 3)
 185:                 fprintf(ddt,"db_load: origin now %s\n", origin);
 186: #endif
 187:             continue;
 188: 
 189:         case DNAME:
 190:             if (!getword(domain, sizeof(domain), fp))
 191:                 break;
 192:             n = strlen(domain) - 1;
 193:             if (domain[n] == '.')
 194:                 domain[n] = '\0';
 195:             else if (*origin) {
 196:                 (void) strcat(domain, ".");
 197:                 (void) strcat(domain, origin);
 198:             }
 199:             goto gotdomain;
 200: 
 201:         case AT:
 202:             (void) strcpy(domain, origin);
 203:             goto gotdomain;
 204: 
 205:         case DOT:
 206:             domain[0] = '\0';
 207:             /* fall thru ... */
 208:         case CURRENT:
 209:         gotdomain:
 210:             if (!getword(buf, sizeof(buf), fp)) {
 211:                 if (c == CURRENT)
 212:                     continue;
 213:                 break;
 214:             }
 215:             cp = buf;
 216:             ttl = 0;
 217:             if (isdigit(*cp)) {
 218:                 n = 0;
 219:                 do
 220:                     n = n * 10 + (*cp++ - '0');
 221:                 while (isdigit(*cp));
 222:                 if (zp->z_type == Z_CACHE) {
 223:                     /* this allows the cache entry to age */
 224:                     /* while sitting on disk (powered off) */
 225:                     if (n > max_cache_ttl)
 226:                     n = max_cache_ttl;
 227:                     n += sb.st_mtime;
 228:                 }
 229:                 ttl = n;
 230:                 if (!getword(buf, sizeof(buf), fp))
 231:                     break;
 232:             }
 233:             for (mp = m_class; mp < m_class+NCLASS; mp++)
 234:                 if (!strcasecmp(buf, mp->token)) {
 235:                     class = mp->val;
 236:                     (void) getword(buf, sizeof(buf), fp);
 237:                     break;
 238:                 }
 239:             for (mp = m_type; mp < m_type+NTYPE; mp++)
 240:                 if (!strcasecmp(buf, mp->token)) {
 241:                     type = mp->val;
 242:                     goto fndtype;
 243:                 }
 244: #ifdef DEBUG
 245:             if (debug)
 246:                 fprintf(ddt,"Line %d: Unknown type: %s.\n",
 247:                     lineno, buf);
 248: #endif
 249:             errs++;
 250:             syslog(LOG_ERR, "Line %d: Unknown type: %s.\n",
 251:                 lineno, buf);
 252:             break;
 253:         fndtype:
 254: #ifdef ALLOW_T_UNSPEC
 255:             /* Don't do anything here for T_UNSPEC...
 256: 			 * read input separately later
 257: 			 */
 258:                         if (type != T_UNSPEC) {
 259: #endif ALLOW_T_UNSPEC
 260:                 if (!getword(buf, sizeof(buf), fp))
 261:                 break;
 262: #ifdef DEBUG
 263:                 if (debug >= 3)
 264:                     fprintf(ddt,
 265:                     "d='%s', c=%d, t=%d, ttl=%ld, data='%s'\n",
 266:                     domain, class, type, ttl, buf);
 267: #endif
 268: #ifdef ALLOW_T_UNSPEC
 269:                         }
 270: #endif ALLOW_T_UNSPEC
 271:             /*
 272: 			 * Convert the ascii data 'buf' to the proper format
 273: 			 * based on the type and pack into 'data'.
 274: 			 */
 275:             switch (type) {
 276:             case T_A:
 277:                 n = ntohl((u_long)inet_addr((char *)buf));
 278:                 cp = data;
 279:                 PUTLONG(n, cp);
 280:                 n = sizeof(u_long);
 281:                 break;
 282: 
 283:             case T_HINFO:
 284:                 n = strlen(buf);
 285:                 if (n > 255) {
 286:                     syslog(LOG_WARNING,
 287:                     "%s: line %d: CPU type too long",
 288:                     filename, lineno);
 289:                     n = 255;
 290:                 }
 291:                 data[0] = n;
 292:                 bcopy(buf, (char *)data + 1, (int)n);
 293:                 n++;
 294:                 if (!getword(buf, sizeof(buf), fp))
 295:                     break;
 296:                 i = strlen(buf);
 297:                 if (i > 255) {
 298:                     syslog(LOG_WARNING,
 299:                     "%s: line %d: OS type too long",
 300:                     filename, lineno);
 301:                     i = 255;
 302:                 }
 303:                 data[n] = i;
 304:                 bcopy(buf, (char *)data + n + 1, i);
 305:                 n += i + 1;
 306:                 endline(fp);
 307:                 break;
 308: 
 309:             case T_SOA:
 310:             case T_MINFO:
 311:                 (void) strcpy(data, buf);
 312:                 makename(data, origin);
 313:                 cp = data + strlen(data) + 1;
 314:                 if (!getword(cp, sizeof(data) - (cp - data),fp)) {
 315:                     n = cp - data;
 316:                     break;
 317:                 }
 318:                 makename(cp, origin);
 319:                 cp += strlen(cp) + 1;
 320:                 if (type == T_MINFO) {
 321:                     n = cp - data;
 322:                     break;
 323:                 }
 324:                 if (getnonblank(fp) != '(')
 325:                     goto err;
 326:                 zp->z_serial = getnum(fp);
 327:                 n = (u_long) zp->z_serial;
 328:                 PUTLONG(n, cp);
 329:                 zp->z_refresh = getnum(fp);
 330:                 n = (u_long) zp->z_refresh;
 331:                 PUTLONG(n, cp);
 332:                 zp->z_time = sb.st_mtime + zp->z_refresh;
 333:                 zp->z_retry = getnum(fp);
 334:                 n = (u_long) zp->z_retry;
 335:                 PUTLONG(n, cp);
 336:                 zp->z_expire = getnum(fp);
 337:                 n = (u_long) zp->z_expire;
 338:                 PUTLONG (n, cp);
 339:                 zp->z_minimum = getnum(fp);
 340:                 n = (u_long) zp->z_minimum;
 341:                 PUTLONG (n, cp);
 342:                 n = cp - data;
 343:                 if (getnonblank(fp) != ')')
 344:                     goto err;
 345:                 endline(fp);
 346:                 break;
 347: 
 348:             case T_UID:
 349:             case T_GID:
 350:                 n = 0;
 351:                 cp = buf;
 352:                 while (isdigit(*cp))
 353:                     n = n * 10 + (*cp++ - '0');
 354:                 if (cp == buf)
 355:                     goto err;
 356:                 cp = data;
 357:                 PUTLONG(n, cp);
 358:                 n = sizeof(long);
 359:                 break;
 360: 
 361:             case T_WKS:
 362:                 /* Address */
 363:                 n = ntohl((u_long)inet_addr((char *)buf));
 364:                 cp = data;
 365:                 PUTLONG(n, cp);
 366:                 *cp = getprotocol(fp, filename);
 367:                 /* Protocol */
 368:                 n = sizeof(u_long) + sizeof(char);
 369:                 /* Services */
 370:                 n = getservices((int)n, data, fp, filename);
 371:                 break;
 372: 
 373:             case T_NS:
 374:             case T_CNAME:
 375:             case T_MB:
 376:             case T_MG:
 377:             case T_MR:
 378:             case T_PTR:
 379:                 (void) strcpy(data, buf);
 380:                 makename(data, origin);
 381:                 n = strlen(data) + 1;
 382:                 break;
 383: 
 384:             case T_UINFO:
 385:                 cp = (u_char *)index(buf, '&');
 386:                 bzero(data, sizeof(data));
 387:                 if ( cp != NULL) {
 388:                     (void) strncpy(data, buf, cp - buf);
 389:                     op = index(domain, '.');
 390:                     if ( op != NULL)
 391:                         (void) strncat(data,
 392:                         domain,op-domain);
 393:                     else
 394:                         (void) strcat(data, domain);
 395:                     (void) strcat(data, ++cp);
 396:                 } else
 397:                     (void) strcpy(data, buf);
 398:                 n = strlen(data) + 1;
 399:                 break;
 400:             case T_MX:
 401:                 n = 0;
 402:                 cp = buf;
 403:                 while (isdigit(*cp))
 404:                     n = n * 10 + (*cp++ - '0');
 405:                 /* catch bad values */
 406:                 if ((cp == buf) || (n > 64535))
 407:                     goto err;
 408: 
 409:                 cp = data;
 410:                 PUTSHORT((u_short)n, cp);
 411: 
 412:                 if (!getword(buf, sizeof(buf), fp))
 413:                         break;
 414:                 (void) strcpy(cp,buf);
 415:                 makename(cp, origin);
 416:                 /* get pointer to place in data */
 417:                 cp += strlen(cp) +1;
 418: 
 419:                 /* now save length */
 420:                 n = (cp - data);
 421:                 break;
 422: #ifdef ALLOW_T_UNSPEC
 423:                         case T_UNSPEC:
 424:                                 {
 425:                                     int rcode;
 426:                                     fgets(buf, sizeof(buf), fp);
 427: #ifdef DEBUG
 428:                     if (debug)
 429:                                         fprintf(ddt, "loading T_UNSPEC\n");
 430: #endif DEBUG
 431:                                     if (rcode = atob(buf, strlen(buf), data,                                                         MAXDATA, &n)) {
 432:                                         if (rcode == CONV_OVERFLOW) {
 433: #ifdef DEBUG
 434:                                             if (debug)
 435:                                                fprintf(ddt,
 436:                                "Load T_UNSPEC: input buffer overflow\n");
 437: #endif DEBUG
 438:                         errs++;
 439:                                             syslog(LOG_ERR,
 440:                          "Load T_UNSPEC: input buffer overflow");
 441:                                          } else {
 442: #ifdef DEBUG
 443:                                             if (debug)
 444:                                                 fprintf(ddt,
 445:                            "Load T_UNSPEC: Data in bad atob format\n");
 446: #endif DEBUG
 447:                         errs++;
 448:                                             syslog(LOG_ERR,
 449:                            "Load T_UNSPEC: Data in bad atob format");
 450:                                          }
 451:                                     }
 452:                                 }
 453:                                 break;
 454: #endif ALLOW_T_UNSPEC
 455: 
 456:             default:
 457:                 goto err;
 458:             }
 459:             dp = savedata(class, type, (u_long)ttl, data, (int)n);
 460:             dp->d_zone = zp - zones;
 461:             dp->d_flags = dataflags;
 462:             if ((c = db_update(domain, dp, dp, dbflags,
 463:                (zp->z_type == Z_CACHE)? fcachetab : hashtab)) < 0) {
 464: #ifdef DEBUG
 465:                 if (debug && (c != DATAEXISTS))
 466:                     fprintf(ddt,"update failed\n");
 467: #endif
 468:             }
 469:             continue;
 470: 
 471:         case ERROR:
 472:             break;
 473:         }
 474:     err:
 475:         errs++;
 476:         syslog(LOG_ERR, "%s: line %d: database format error (%s)",
 477:             filename, lineno, buf);
 478: #ifdef DEBUG
 479:         if (debug)
 480:             fprintf(ddt,"%s: line %d: database format error ('%s', %d)\n",
 481:                 filename, lineno, buf, n);
 482: #endif
 483:         while ((c = getc(fp)) != EOF && c != '\n')
 484:             ;
 485:         if (c == '\n')
 486:             lineno++;
 487:     }
 488:     (void) fclose(fp);
 489:     if (didinclude)
 490:         zp->z_ftime = 0;
 491:     else
 492:         zp->z_ftime = sb.st_mtime;
 493:     zp->z_lastupdate = sb.st_mtime;
 494:     lineno = slineno;
 495:     return (errs);
 496: }
 497: 
 498: int gettoken(fp)
 499:     register FILE *fp;
 500: {
 501:     register int c;
 502:     char op[32];
 503: 
 504:     for (;;) {
 505:         c = getc(fp);
 506:     top:
 507:         switch (c) {
 508:         case EOF:
 509:             return (EOF);
 510: 
 511:         case '$':
 512:             if (getword(op, sizeof(op), fp)) {
 513:                 if (!strcasecmp("include", op))
 514:                     return (INCLUDE);
 515:                 if (!strcasecmp("origin", op))
 516:                     return (ORIGIN);
 517:             }
 518: #ifdef DEBUG
 519:             if (debug)
 520:                 fprintf(ddt,"Line %d: Unknown $ option: $%s\n",
 521:                     lineno, op);
 522: #endif
 523:             syslog(LOG_ERR,"Line %d: Unknown $ option: $%s\n",
 524:                 lineno, op);
 525:             return (ERROR);
 526: 
 527:         case ';':
 528:             while ((c = getc(fp)) != EOF && c != '\n')
 529:                 ;
 530:             goto top;
 531: 
 532:         case ' ':
 533:         case '\t':
 534:             return (CURRENT);
 535: 
 536:         case '.':
 537:             return (DOT);
 538: 
 539:         case '@':
 540:             return (AT);
 541: 
 542:         case '\n':
 543:             lineno++;
 544:             continue;
 545: 
 546:         default:
 547:             (void) ungetc(c, fp);
 548:             return (DNAME);
 549:         }
 550:     }
 551: }
 552: 
 553: /*
 554:  * Get next word, skipping blanks & comments.
 555:  */
 556: getword(buf, size, fp)
 557:     char *buf;
 558:     int size;
 559:     FILE *fp;
 560: {
 561:     register char *cp;
 562:     register int c;
 563: 
 564:     for (cp = buf; (c = getc(fp)) != EOF; ) {
 565:         if (c == ';') {
 566:             while ((c = getc(fp)) != EOF && c != '\n')
 567:                 ;
 568:             c = '\n';
 569:         }
 570:         if (c == '\n') {
 571:             if (cp != buf)
 572:                 ungetc(c, fp);
 573:             else
 574:                 lineno++;
 575:             break;
 576:         }
 577:         if (isspace(c)) {
 578:             while (isspace(c = getc(fp)) && c != '\n')
 579:                 ;
 580:             ungetc(c, fp);
 581:             if (cp != buf)      /* Trailing whitespace */
 582:                 break;
 583:             continue;       /* Leading whitespace */
 584:         }
 585:         if (c == '"') {
 586:             while ((c = getc(fp)) != EOF && c != '"' && c != '\n') {
 587:                 if (c == '\\') {
 588:                     if ((c = getc(fp)) == EOF)
 589:                         c = '\\';
 590:                     if (c == '\n')
 591:                         lineno++;
 592:                 }
 593:                 if (cp >= buf+size-1)
 594:                     break;
 595:                 *cp++ = c;
 596:             }
 597:             if (c == '\n') {
 598:                 lineno++;
 599:                 break;
 600:             }
 601:             continue;
 602:         }
 603:         if (c == '\\') {
 604:             if ((c = getc(fp)) == EOF)
 605:                 c = '\\';
 606:             if (c == '\n')
 607:                 lineno++;
 608:         }
 609:         if (cp >= buf+size-1)
 610:             break;
 611:         *cp++ = c;
 612:     }
 613:     *cp = '\0';
 614:     return (cp != buf);
 615: }
 616: 
 617: u_long
 618: getnum(fp)
 619:     FILE *fp;
 620: {
 621:     register int c;
 622:     u_long 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%lx mask x%lx", ntp,
 897:             ntp->net, ntp->mask);
 898:             fprintf(ddt," my_addr x%lx", 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: }

Defined functions

buildprotolist defined in line 926; used 1 times
buildservicelist defined in line 905; used 1 times
cgetprotobynumber defined in line 998; used 2 times
cgetservbyport defined in line 967; used 2 times
db_load defined in line 105; used 4 times
endline defined in line 731; used 9 times
findservice defined in line 946; used 2 times
get_sort_list defined in line 833; used 1 times
getnonblank defined in line 668; used 2 times
getnum defined in line 617; used 6 times
getprotocol defined in line 746; used 1 times
getservices defined in line 765; used 1 times
gettoken defined in line 498; used 1 times
getword defined in line 556; used 23 times
makename defined in line 703; used 6 times

Defined variables

lineno defined in line 92; used 37 times
m_class defined in line 46; used 3 times
m_type defined in line 55; used 3 times
protolist defined in line 99; used 6 times
sccsid defined in line 14; never used
servicelist defined in line 99; used 6 times

Defined struct's

map defined in line 41; used 6 times
valuelist defined in line 94; used 26 times

Defined macros

AT defined in line 86; used 1 times
CURRENT defined in line 84; used 2 times
DNAME defined in line 87; used 1 times
DOT defined in line 85; used 1 times
ERROR defined in line 90; used 1 times
INCLUDE defined in line 88; used 1 times
MAXLEN defined in line 744; used 2 times
MAXPORT defined in line 743; used 3 times
NCLASS defined in line 53; used 1 times
NTYPE defined in line 79; used 1 times
ORIGIN defined in line 89; used 1 times
Last modified: 1988-09-10
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 6333
Valid CSS Valid XHTML 1.0 Strict