# 2.11BSD#431 - /usr/src/usr.sbin/named/named/db_dump.c

##### Functions

    atob              X
    btoa              X
    db_dump           X
    doachkpt          X
    doadump           X
    mark_cache        X
    p_protocal        X
    p_service         X
    scan_root         X
    zonedump          X

##### Variables

    dumpfile          X

##### Macros

    AddToBuf          X
    Ceor              X
    Crot              X
    Csum              X
    DB_ROOT_TIMBUF    X
    DE                X
    EN                X
    TIMBUF            X
    bcount            X
    streq             X
    times85           X
    word              X

       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_dump.c	4.20 (Berkeley) 2/17/88";
      15: #endif /* not lint */
      16:
      17: #include <sys/param.h>
      18: #include <sys/time.h>
      19: #include <sys/stat.h>
      20: #include <netinet/in.h>
      21: #include <netdb.h>
      22: #include <stdio.h>
      23: #include <syslog.h>
      24: #include <arpa/nameser.h>
      25: #include "ns.h"
      26: #include "db.h"
      27:
      28: extern  char *p_type(), *p_class();
      29:
      30: #ifdef DUMPFILE
      31: char    *dumpfile = DUMPFILE;
      32: #else
      33: char    *dumpfile = "/usr/tmp/named_dump.db";
      34: #endif
      35:
      36: extern char *cache_file;
      37:
      38: /*
      39:  * Dump current cache in a format similar to RFC 883.
      40:  *
      41:  * We try to be careful and determine whether the operation succeeded
      42:  * so that the new cache file can be installed.
      43:  */
      44:
      45: #define DB_ROOT_TIMBUF 3600
      46:
      47: doachkpt()
      48: {
      49:     extern int errno;
      50:     FILE *fp;
      51:     char tmpcheckfile[256];
      52:
      53:     /* nowhere to checkpoint cache... */
      54:     if (cache_file == NULL) {
      55: #ifdef DEBUG
      56:         if (debug >= 3)
      57:             fprintf(ddt,"doachkpt(to where?)\n");
      58: #endif
      59:         return;
      60:     }
      61:
      62: #ifdef DEBUG
      63:     if (debug >= 3)
      64:         fprintf(ddt,"doachkpt()\n");
      65: #endif
      66:
      67:     (void) sprintf(tmpcheckfile, "%s.chk", cache_file);
      68:     if ((fp = fopen(tmpcheckfile, "w")) == NULL) {
      69: #ifdef DEBUG
      70:         if (debug >= 3)
      71:             fprintf(ddt,"doachkpt(can't open %s for write)\n", tmpcheckfile);
      72: #endif
      73:         return;
      74:     }
      75:
      76:     (void) gettime(&tt);
      77:     fprintf(fp, "; Dumped at %s", ctime(&tt.tv_sec));
      78:     fflush(fp);
      79:     if (ferror(fp)) {
      80: #ifdef DEBUG
      81:         if (debug >= 3)
      82:             fprintf(ddt,"doachkpt(write to checkpoint file failed)\n");
      83: #endif
      84:         return;
      85:     }
      86:
      87:     if (fcachetab != NULL) {
      88:     int n;
      89:     if ((n = scan_root(hashtab)) < MINROOTS) {
      90:         syslog(LOG_ERR, "%d root hints... (too low)", n);
      91:         fprintf(fp, "; ---- Root hint cache dump ----\n");
      92:         (void) db_dump(fcachetab, fp, DB_Z_CACHE, "");
      93:     }
      94:     }
      95:
      96:     if (hashtab != NULL) {
      97:         fprintf(fp, "; ---- Cache dump ----\n");
      98:         if (db_dump(hashtab, fp, DB_Z_CACHE, "") == NODBFILE) {
      99: #ifdef DEBUG
     100:             if (debug >= 3)
     101:                 fprintf(ddt,"doachkpt(checkpoint failed)\n");
     102: #endif
     103:             (void) fclose(fp);
     104:             return;
     105:         }
     106:     }
     107:
     108:     (void) fsync(fileno(fp));
     109:     if (fclose(fp) == EOF) {
     110: #ifdef DEBUG
     111:         if (debug >= 3)
     112:             fprintf(ddt,"doachkpt(close failed)\n");
     113: #endif
     114:         return;
     115:     }
     116:
     117:     if (rename(tmpcheckfile, cache_file)) {
     118: #ifdef DEBUG
     119:         if (debug >= 3)
     120:             fprintf(ddt,"doachkpt(install %s to %s failed, %d)\n",
     121:                     tmpcheckfile,cache_file, errno);
     122: #endif
     123:     }
     124: }
     125:
     126: /*
     127:  * What we do is scan the root hint cache to make sure there are at least
     128:  * MINROOTS root pointers with non-0 TTL's so that the checkpoint will not
     129:  * lose the root.  Failing this, all pointers are written out w/ TTL ~0
     130:  * (root pointers timed out and prime_cache() not done or failed).
     131:  */
     132: #define TIMBUF 300
     133:
     134: int
     135: scan_root(htp)
     136:     struct hashbuf *htp;
     137: {
     138:     register struct databuf *dp;
     139:     register struct namebuf *np;
     140:     struct timeval soon;
     141:     int roots = 0;
     142:
     143: #ifdef DEBUG
     144:     if (debug)
     145:         fprintf(ddt,"scan_root(0x%x)\n", htp);
     146: #endif
     147:
     148:     /* metric by which we determine whether a root NS pointer is still */
     149:     /* valid (will be written out if we do a dump).  we also add some */
     150:     /* time buffer for safety... */
     151:     (void) gettime(&soon);
     152:     soon.tv_sec += TIMBUF;
     153:
     154:     for (np = htp->h_tab[0]; np != NULL; np = np->n_next) {
     155:         if (np->n_dname[0] == '\0') {
     156:             dp = np->n_data;
     157:             while (dp != NULL) {
     158:                 if (dp->d_type == T_NS &&
     159:                     dp->d_ttl > soon.tv_sec) {
     160:                     roots++;
     161:                     if (roots >= MINROOTS)
     162:                         return (roots);
     163:                 }
     164:                 dp = dp->d_next;
     165:             }
     166:         }
     167:     }
     168:     return (roots);
     169: }
     170:
     171: #ifdef notdef
     172: mark_cache(htp, ttl)
     173:     struct hashbuf *htp;
     174:     u_long ttl;
     175: {
     176:     register struct databuf *dp;
     177:     register struct namebuf *np;
     178:     struct namebuf **npp, **nppend;
     179:     struct timeval soon;
     180:
     181: #ifdef DEBUG
     182:     if (debug)
     183:         fprintf(ddt,"mark_cache()\n");
     184: #endif
     185:
     186:     (void) gettime(&soon);
     187:     soon.tv_sec += TIMBUF;
     188:
     189:     npp = htp->h_tab;
     190:     nppend = npp + htp->h_size;
     191:     while (npp < nppend) {
     192:         for (np = *npp++; np != NULL; np = np->n_next) {
     193:             if (np->n_data == NULL)
     194:                 continue;
     195:             for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
     196:                 if (dp->d_ttl < soon.tv_sec)
     197:                     dp->d_ttl = ttl;
     198:             }
     199:         }
     200:     }
     201:
     202:     npp = htp->h_tab;
     203:     nppend = npp + htp->h_size;
     204:     while (npp < nppend) {
     205:         for (np = *npp++; np != NULL; np = np->n_next) {
     206:             if (np->n_hash == NULL)
     207:                 continue;
     208:             mark_cache(np->n_hash, ttl);
     209:         }
     210:     }
     211: }
     212: #endif notdef
     213:
     214: /*
     215:  * Dump current data base in a format similar to RFC 883.
     216:  */
     217:
     218: doadump()
     219: {
     220:     FILE    *fp;
     221:
     222: #ifdef DEBUG
     223:     if (debug >= 3)
     224:         fprintf(ddt,"doadump()\n");
     225: #endif
     226:
     227:     if ((fp = fopen(dumpfile, "w")) == NULL)
     228:         return;
     229:     gettime(&tt);
     230:     fprintf(fp, "; Dumped at %s", ctime(&tt.tv_sec));
     231:     fprintf(fp, "; --- Cache & Data ---\n");
     232:     if (hashtab != NULL)
     233:         (void) db_dump(hashtab, fp, DB_Z_ALL, "");
     234:     fprintf(fp, "; --- Hints ---\n");
     235:     if (fcachetab != NULL)
     236:         (void) db_dump(fcachetab, fp, DB_Z_ALL, "");
     237:     (void) fclose(fp);
     238: }
     239:
     240: /* Create a disk database to back up zones
     241:  */
     242: zonedump(zp)
     243:     register struct zoneinfo *zp;
     244: {
     245:     FILE    *fp;
     246:     char *fname;
     247:     struct hashbuf *htp;
     248:     char *op;
     249:     struct stat st;
     250:
     251:     /* Only dump zone if there is a cache specified */
     252:     if (zp->z_source && *(zp->z_source)) {
     253: #ifdef DEBUG
     254:         if (debug)
     255:             fprintf(ddt, "zonedump(%s)\n", zp->z_source);
     256: #endif
     257:
     258:         if ((fp = fopen(zp->z_source, "w")) == NULL)
     259:             return;
     260:         if (op = index(zp->z_origin, '.'))
     261:         op++;
     262:         gettime(&tt);
     263:         htp = hashtab;
     264:         if (nlookup(zp->z_origin, &htp, &fname, 0) != NULL) {
     265:             db_dump(htp, fp, zp-zones, (op == NULL ? "" : op));
     266: #ifdef ALLOW_UPDATES
     267:             zp->hasChanged = 0;     /* Checkpointed */
     268: #endif ALLOW_UPDATES
     269:         }
     270:         (void) fclose(fp);
     271:         if (stat(zp->z_source, &st) == 0)
     272:             zp->z_ftime = st.st_mtime;
     273:     }
     274: #ifdef DEBUG
     275:         else if (debug)
     276:         fprintf(ddt, "zonedump: no zone to dump\n");
     277: #endif
     278: }
     279:
     280: int
     281: db_dump(htp, fp, zone, origin)
     282:     int zone;
     283:     struct hashbuf *htp;
     284:     FILE *fp;
     285:     char *origin;
     286: {
     287:     register struct databuf *dp;
     288:     register struct namebuf *np;
     289:     struct namebuf **npp, **nppend;
     290:     char dname[MAXDNAME];
     291:     u_long n;
     292:     u_long addr;
     293:     u_short i;
     294:     int j;
     295:     register u_char *cp;
     296:     char *proto;
     297:     extern char *inet_ntoa(), *p_protocal(), *p_service();
     298:     int found_data, tab, printed_origin = 0;
     299:
     300:     npp = htp->h_tab;
     301:     nppend = npp + htp->h_size;
     302:     while (npp < nppend) {
     303:         for (np = *npp++; np != NULL; np = np->n_next) {
     304:         if (np->n_data == NULL)
     305:             continue;
     306:         /* Blecch - can't tell if there is data here for the
     307: 		 * right zone, so can't print name yet
     308: 		 */
     309:         found_data = 0;
     310:         /* we want a snapshot in time... */
     311:         for (dp = np->n_data; dp != NULL; dp = dp->d_next) {
     312:             /* Is the data for this zone? */
     313:             if (zone != DB_Z_ALL && dp->d_zone != zone)
     314:                 continue;
     315:             if (dp->d_zone == DB_Z_CACHE &&
     316:                 dp->d_ttl <= tt.tv_sec &&
     317:                 (dp->d_flags & DB_F_HINT) == 0)
     318:                 continue;
     319:             if (!printed_origin) {
     320:                 fprintf(fp, "$ORIGIN %s.\n", origin);
     321:                 printed_origin++;
     322:             }
     323:             tab = 0;
     324:             if (!found_data) {
     325:                 if (np->n_dname[0] == 0) {
     326:                 if (origin[0] == 0)
     327:                     fprintf(fp, ".\t");
     328:                 else
     329:                     fprintf(fp, ".%s.\t", origin); /* ??? */
     330:                 } else
     331:                 fprintf(fp, "%s\t", np->n_dname);
     332:                 if (strlen(np->n_dname) < 8)
     333:                 tab = 1;
     334:                 found_data++;
     335:             } else {
     336:                 (void) putc('\t', fp);
     337:                 tab = 1;
     338:             }
     339:             if (dp->d_zone == DB_Z_CACHE) {
     340:                 if (dp->d_flags & DB_F_HINT &&
     341:                     (long)(dp->d_ttl - tt.tv_sec) < DB_ROOT_TIMBUF)
     342:                     fprintf(fp, "%d\t", DB_ROOT_TIMBUF);
     343:                 else
     344:                     fprintf(fp, "%ld\t",
     345:                     (dp->d_ttl - tt.tv_sec));
     346:             } else if (dp->d_ttl != 0 &&
     347:                 dp->d_ttl != zones[dp->d_zone].z_minimum)
     348:                 fprintf(fp, "%ld\t", dp->d_ttl);
     349:             else if (tab)
     350:                 (void) putc('\t', fp);
     351:             fprintf(fp, "%s\t%s\t", p_class(dp->d_class),
     352:                 p_type(dp->d_type));
     353:             cp = (u_char *)dp->d_data;
     354:             /*
     355: 			 * Print type specific data
     356: 			 */
     357:             switch (dp->d_type) {
     358:             case T_A:
     359:                 switch (dp->d_class) {
     360:                 case C_IN:
     361:                     GETLONG(n, cp);
     362:                     n = htonl(n);
     363:                     fprintf(fp, "%s",
     364:                        inet_ntoa(*(struct in_addr *)&n));
     365:                     break;
     366:                 }
     367:                 if (dp->d_nstime)
     368:                     fprintf(fp, "\t; %ld", dp->d_nstime);
     369:                 fprintf(fp, "\n");
     370:                 break;
     371:             case T_CNAME:
     372:             case T_MB:
     373:             case T_MG:
     374:             case T_MR:
     375:             case T_PTR:
     376:                 if (cp[0] == '\0')
     377:                     fprintf(fp, ".\n");
     378:                 else
     379:                     fprintf(fp, "%s.\n", cp);
     380:                 break;
     381:
     382:             case T_NS:
     383:                 cp = (u_char *)dp->d_data;
     384:                 if (cp[0] == '\0')
     385:                     fprintf(fp, ".\t");
     386:                 else
     387:                     fprintf(fp, "%s.", cp);
     388:                 if (dp->d_nstime)
     389:                     fprintf(fp, "\t; %ld???", dp->d_nstime);
     390:                 fprintf(fp, "\n");
     391:                 break;
     392:
     393:             case T_HINFO:
     394:                 if (n = *cp++) {
     395:                     fprintf(fp, "\"%.*s\"", (int)n, cp);
     396:                     cp += n;
     397:                 } else
     398:                     fprintf(fp, "\"\"");
     399:                 if (n = *cp++)
     400:                     fprintf(fp, " \"%.*s\"", (int)n, cp);
     401:                 else
     402:                     fprintf(fp, "\"\"");
     403:                 (void) putc('\n', fp);
     404:                 break;
     405:
     406:             case T_SOA:
     407:                 fprintf(fp, "%s.", cp);
     408:                 cp += strlen(cp) + 1;
     409:                 fprintf(fp, " %s. (\n", cp);
     410:                 cp += strlen(cp) + 1;
     411:                 GETLONG(n, cp);
     412:                 fprintf(fp, "\t\t%lu", n);
     413:                 GETLONG(n, cp);
     414:                 fprintf(fp, " %lu", n);
     415:                 GETLONG(n, cp);
     416:                 fprintf(fp, " %lu", n);
     417:                 GETLONG(n, cp);
     418:                 fprintf(fp, " %lu", n);
     419:                 GETLONG(n, cp);
     420:                 fprintf(fp, " %lu )\n", n);
     421:                 break;
     422:
     423:             case T_MX:
     424:                 GETSHORT(n, cp);
     425:                 fprintf(fp,"%lu", n);
     426:                 fprintf(fp," %s.\n", cp);
     427:                 break;
     428:
     429:
     430:             case T_UINFO:
     431:                 fprintf(fp, "\"%s\"\n", cp);
     432:                 break;
     433:
     434:             case T_UID:
     435:             case T_GID:
     436:                 if (dp->d_size == sizeof(u_long)) {
     437:                     GETLONG(n, cp);
     438:                     fprintf(fp, "%lu\n", n);
     439:                 }
     440:                 break;
     441:
     442:             case T_WKS:
     443:                 GETLONG(addr, cp);
     444:                 addr = htonl(addr);
     445:                 fprintf(fp,"%s ",
     446:                     inet_ntoa(*(struct in_addr *)&addr));
     447:                 proto = p_protocal(*cp); /* protocal */
     448:                 cp += sizeof(char);
     449:                 fprintf(fp, "%s ", proto);
     450:                 i = 0;
     451:                 while(cp < (u_char *)dp->d_data + dp->d_size) {
     452:                     j = *cp++;
     453:                     do {
     454:                         if(j & 0200)
     455:                             fprintf(fp," %s",
     456:                                p_service(i, proto));
     457:                         j <<= 1;
     458:                     } while(++i & 07);
     459:                 }
     460:                 fprintf(fp,"\n");
     461:                 break;
     462:
     463:             case T_MINFO:
     464:                 fprintf(fp, "%s.", cp);
     465:                 cp += strlen(cp) + 1;
     466:                 fprintf(fp, " %s.\n", cp);
     467:                 break;
     468: #ifdef ALLOW_T_UNSPEC
     469:             case T_UNSPEC:
     470:                 /* Dump binary data out in an ASCII-encoded
     471: 				   format */
     472:                 {
     473:                     /* Allocate more than enough space:
     474: 					 *  actually need 5/4 size + 20 or so
     475: 					 */
     476:                     int TmpSize = 2 * dp->d_size + 30;
     477:                     char *TmpBuf = (char *) malloc(TmpSize);
     478:                     if (TmpBuf == NULL) {
     479: #ifdef DEBUG
     480:                         if (debug)
     481:                         fprintf(ddt, "Dump T_UNSPEC: malloc returned NULL\n");
     482: #endif DEBUG
     483:                         syslog(LOG_ERR, "Dump T_UNSPEC: malloc: %m");
     484:                     }
     485:                     if (btoa(cp, dp->d_size, TmpBuf,
     486:                          TmpSize) == CONV_OVERFLOW) {
     487: #ifdef DEBUG
     488:                         if (debug)
     489:                             fprintf(ddt, "Dump T_UNSPEC: Output buffer overflow\n");
     490: #endif DEBUG
     491:                             syslog(LOG_ERR, "Dump T_UNSPEC: Output buffer overflow\n");
     492:                     } else
     493:                         fprintf(fp, "%s\n", TmpBuf);
     494:                 }
     495:                 break;
     496: #endif ALLOW_T_UNSPEC
     497:             default:
     498:                 fprintf(fp, "???\n");
     499:             }
     500:         }
     501:         }
     502:     }
     503:         if (ferror(fp))
     504:             return(NODBFILE);
     505:
     506:     npp = htp->h_tab;
     507:     nppend = npp + htp->h_size;
     508:     while (npp < nppend) {
     509:         for (np = *npp++; np != NULL; np = np->n_next) {
     510:         if (np->n_hash == NULL)
     511:             continue;
     512:         getname(np, dname, sizeof(dname));
     513:         if (db_dump(np->n_hash, fp, zone, dname) == NODBFILE)
     514:             return(NODBFILE);
     515:         }
     516:     }
     517:     return(OK);
     518: }
     519:
     520: /*  These next two routines will be moveing to res_debug.c */
     521: /* They are currently here for ease of distributing the WKS record fix */
     522: char *
     523: p_protocal(num)
     524: int num;
     525: {
     526:     static  char number[8];
     527:     struct protoent *pp;
     528:     extern struct protoent *cgetprotobynumber();
     529:
     530:     pp = cgetprotobynumber(num);
     531:     if(pp == 0)  {
     532:         (void) sprintf(number, "%d", num);
     533:         return(number);
     534:     }
     535:     return(pp->p_name);
     536: }
     537:
     538: char *
     539: p_service(port, proto)
     540: u_short port;
     541: char *proto;
     542: {
     543:     static  char number[8];
     544:     struct servent *ss;
     545:     extern struct servent *cgetservbyport();
     546:
     547:     ss = cgetservbyport(htons(port), proto);
     548:     if(ss == 0)  {
     549:         (void) sprintf(number, "%d", port);
     550:         return(number);
     551:     }
     552:     return(ss->s_name);
     553: }
     554:
     555: #ifdef ALLOW_T_UNSPEC
     556: /*
     557:  * Subroutines to convert between 8 bit binary bytes and printable ASCII.
     558:  * Computes the number of bytes, and three kinds of simple checksums.
     559:  * Incoming bytes are collected into 32-bit words, then printed in base 85:
     560:  *	exp(85,5) > exp(2,32)
     561:  * The ASCII characters used are between '!' and 'u';
     562:  * 'z' encodes 32-bit zero; 'x' is used to mark the end of encoded data.
     563:  *
     564:  * Originally by Paul Rutter (philabs!per) and Joe Orost (petsd!joe) for
     565:  * the atob/btoa programs, released with the compress program, in mod.sources.
     566:  * Modified by Mike Schwartz 8/19/86 for use in BIND.
     567:  */
     568:
     569: /* Make sure global variable names are unique */
     570: #define Ceor T_UNSPEC_Ceor
     571: #define Csum T_UNSPEC_Csum
     572: #define Crot T_UNSPEC_Crot
     573: #define word T_UNSPEC_word
     574: #define bcount T_UNSPEC_bcount
     575:
     576: static long int Ceor, Csum, Crot, word, bcount;
     577:
     578: #define EN(c)   ((int) ((c) + '!'))
     579: #define DE(c) ((c) - '!')
     580: #define AddToBuf(bufp, c) **bufp = c; (*bufp)++;
     581: #define streq(s0, s1)   strcmp(s0, s1) == 0
     582: #define times85(x)  ((((((x<<2)+x)<<2)+x)<<2)+x)
     583:
     584:
     585: /* Decode ASCII-encoded byte c into binary representation and
     586:  * place into *bufp, advancing bufp
     587:  */
     588: static int
     589: byte_atob(c, bufp)
     590:     register c;
     591:     char **bufp;
     592: {
     593:     if (c == 'z') {
     594:         if (bcount != 0)
     595:             return(CONV_BADFMT);
     596:         else {
     597:             putbyte(0, bufp);
     598:             putbyte(0, bufp);
     599:             putbyte(0, bufp);
     600:             putbyte(0, bufp);
     601:         }
     602:     } else if ((c >= '!') && (c < ('!' + 85))) {
     603:         if (bcount == 0) {
     604:             word = DE(c);
     605:             ++bcount;
     606:         } else if (bcount < 4) {
     607:             word = times85(word);
     608:             word += DE(c);
     609:             ++bcount;
     610:         } else {
     611:             word = times85(word) + DE(c);
     612:             putbyte((int)((word >> 24) & 255), bufp);
     613:             putbyte((int)((word >> 16) & 255), bufp);
     614:             putbyte((int)((word >> 8) & 255), bufp);
     615:             putbyte((int)(word & 255), bufp);
     616:             word = 0;
     617:             bcount = 0;
     618:         }
     619:     } else
     620:         return(CONV_BADFMT);
     621:     return(CONV_SUCCESS);
     622: }
     623:
     624: /* Compute checksum info and place c into *bufp, advancing bufp */
     625: static
     626: putbyte(c, bufp)
     627:     register c;
     628:     char **bufp;
     629: {
     630:     Ceor ^= c;
     631:     Csum += c;
     632:     Csum += 1;
     633:     if ((Crot & 0x80000000)) {
     634:         Crot <<= 1;
     635:         Crot += 1;
     636:     } else {
     637:         Crot <<= 1;
     638:     }
     639:     Crot += c;
     640:     AddToBuf(bufp, c);
     641: }
     642:
     643: /* Read the ASCII-encoded data from inbuf, of length inbuflen, and convert
     644:    it into T_UNSPEC (binary data) in outbuf, not to exceed outbuflen bytes;
     645:    outbuflen must be divisible by 4.  (Note: this is because outbuf is filled
     646:    in 4 bytes at a time.  If the actual data doesn't end on an even 4-byte
     647:    boundary, there will be no problem...it will be padded with 0 bytes, and
     648:    numbytes will indicate the correct number of bytes.  The main point is
     649:    that since the buffer is filled in 4 bytes at a time, even if there is
     650:    not a full 4 bytes of data at the end, there has to be room to 0-pad the
     651:    data, so the buffer must be of size divisible by 4).  Place the number of
     652:    output bytes in numbytes, and return a failure/success status  */
     653: int
     654: atob(inbuf, inbuflen, outbuf, outbuflen, numbytes)
     655:     char *inbuf;
     656:     int inbuflen;
     657:     char *outbuf;
     658:     int outbuflen;
     659:     int *numbytes;
     660: {
     661:     int inc, nb;
     662:     long int oeor, osum, orot;
     663:     char *inp, *outp = outbuf, *endoutp = &outbuf[outbuflen];
     664:
     665:     if ( (outbuflen % 4) != 0)
     666:         return(CONV_BADBUFLEN);
     667:     Ceor = Csum = Crot = word = bcount = 0;
     668:     for (inp = inbuf, inc = 0; inc < inbuflen; inp++, inc++) {
     669:         if (outp > endoutp)
     670:             return(CONV_OVERFLOW);
     671:         if (*inp == 'x') {
     672:             inp +=2;
     673:             break;
     674:         } else {
     675:             if (byte_atob(*inp, &outp) == CONV_BADFMT)
     676:                 return(CONV_BADFMT);
     677:         }
     678:     }
     679:
     680:     /* Get byte count and checksum information from end of buffer */
     681:     if(sscanf(inp, "%ld %lx %lx %lx", numbytes, &oeor, &osum, &orot) != 4)
     682:         return(CONV_BADFMT);
     683:     if ((oeor != Ceor) || (osum != Csum) || (orot != Crot))
     684:         return(CONV_BADCKSUM);
     685:     return(CONV_SUCCESS);
     686: }
     687:
     688: /* Encode binary byte c into ASCII representation and place into *bufp,
     689:    advancing bufp */
     690: static
     691: byte_btoa(c, bufp)
     692:     register c;
     693:     char **bufp;
     694: {
     695:     Ceor ^= c;
     696:     Csum += c;
     697:     Csum += 1;
     698:     if ((Crot & 0x80000000)) {
     699:         Crot <<= 1;
     700:         Crot += 1;
     701:     } else {
     702:         Crot <<= 1;
     703:     }
     704:     Crot += c;
     705:
     706:     word <<= 8;
     707:     word |= c;
     708:     if (bcount == 3) {
     709:         if (word == 0) {
     710:             AddToBuf(bufp, 'z');
     711:         } else {
     712:             register int tmp = 0;
     713:             register long int tmpword = word;
     714:
     715:             if (tmpword < 0) {
     716:                /* Because some don't support unsigned long */
     717:                 tmp = 32;
     718:                 tmpword -= (long)(85 * 85 * 85 * 85 * 32);
     719:             }
     720:             if (tmpword < 0) {
     721:                 tmp = 64;
     722:                 tmpword -= (long)(85 * 85 * 85 * 85 * 32);
     723:             }
     724:             AddToBuf(bufp,
     725:                  EN((tmpword / (long)(85 * 85 * 85 * 85)) + tmp));
     726:             tmpword %= (long)(85 * 85 * 85 * 85);
     727:             AddToBuf(bufp, EN(tmpword / (85 * 85 * 85)));
     728:             tmpword %= (85 * 85 * 85);
     729:             AddToBuf(bufp, EN(tmpword / (85 * 85)));
     730:             tmpword %= (85 * 85);
     731:             AddToBuf(bufp, EN(tmpword / 85));
     732:             tmpword %= 85;
     733:             AddToBuf(bufp, EN(tmpword));
     734:         }
     735:         bcount = 0;
     736:     } else {
     737:         bcount += 1;
     738:     }
     739: }
     740:
     741:
     742: /*
     743:  * Encode the binary data from inbuf, of length inbuflen, into a
     744:  * null-terminated ASCII representation in outbuf, not to exceed outbuflen
     745:  * bytes. Return success/failure status
     746:  */
     747: int
     748: btoa(inbuf, inbuflen, outbuf, outbuflen)
     749:     char *inbuf;
     750:     int inbuflen;
     751:     char *outbuf;
     752:     int outbuflen;
     753: {
     754:     long int inc, nb;
     755:     long int oeor, osum, orot;
     756:     char *inp, *outp = outbuf, *endoutp = &outbuf[outbuflen -1];
     757:
     758:     Ceor = Csum = Crot = word = bcount = 0;
     759:     for (inp = inbuf, inc = 0; inc < inbuflen; inp++, inc++) {
     760:         byte_btoa((unsigned char) (*inp), &outp);
     761:         if (outp >= endoutp)
     762:             return(CONV_OVERFLOW);
     763:     }
     764:     while (bcount != 0) {
     765:         byte_btoa(0, &outp);
     766:         if (outp >= endoutp)
     767:             return(CONV_OVERFLOW);
     768:     }
     769:     /* Put byte count and checksum information at end of buffer, delimited
     770: 	   by 'x' */
     771:     (void) sprintf(outp, "x %ld %lx %lx %lx", inbuflen, Ceor, Csum, Crot);
     772:     if (&outp[strlen(outp) - 1] >= endoutp)
     773:         return(CONV_OVERFLOW);
     774:     else
     775:         return(CONV_SUCCESS);
     776: }
     777: #endif ALLOW_T_UNSPEC

#### Defined functions

atob defined in line 653; used 1 times

- in /usr/src/usr.sbin/named/named/db_load.c line 431

btoa defined in line 747; used 1 times

- in line 485

byte_atob defined in line 588; used 1 times

- in line 675

byte_btoa defined in line 690; used 2 times

- in line 760-765(2)

db_dump defined in line 280; used 6 times

- in line 92, 98, 233-236(2), 265, 513

doachkpt defined in line 47; used 2 times

- in /usr/src/usr.sbin/named/named/ns_main.c line 624
- in /usr/src/usr.sbin/named/named/ns_maint.c line 73

doadump defined in line 218; used 1 times

- in /usr/src/usr.sbin/named/named/ns_main.c line 628

mark_cache defined in line 172; used 1 times

- in line 208

p_protocal defined in line 522; used 4 times

- in line 297, 447
- in /usr/src/usr.sbin/named/named/ns_sort.c line 148, 260

p_service defined in line 538; used 4 times

- in line 297, 456
- in /usr/src/usr.sbin/named/named/ns_sort.c line 148, 269

putbyte defined in line 625; used 8 times

- in line 597-600(4), 612-615(4)

scan_root defined in line 134; used 1 times

- in line 89

zonedump defined in line 242; used 3 times

- in /usr/src/usr.sbin/named/named/ns_main.c line 603
- in /usr/src/usr.sbin/named/named/ns_maint.c line 82, 447

#### Defined variables

Ceor defined in line 576; never used
Crot defined in line 576; never used
Csum defined in line 576; never used
bcount defined in line 576; never used
dumpfile defined in line 33; used 1 times

- in line 227

sccsid defined in line 14; never used
word defined in line 576; never used

#### Defined macros

AddToBuf defined in line 580; used 7 times

- in line 640, 710, 724-733(5)

Ceor defined in line 570; used 6 times

- in line 630, 667, 683, 695, 758, 771

Crot defined in line 572; used 14 times

- in line 633-639(5), 667, 683, 698-704(5), 758, 771

Csum defined in line 571; used 8 times

- in line 631-632(2), 667, 683, 696-697(2), 758, 771

DB_ROOT_TIMBUF defined in line 45; used 2 times

- in line 341-342(2)

DE defined in line 579; used 3 times

- in line 604-611(3)

EN defined in line 578; used 5 times

- in line 725-733(5)

TIMBUF defined in line 132; used 2 times

- in line 152, 187

bcount defined in line 574; used 12 times

- in line 594, 603-609(4), 617, 667, 708, 735-737(2), 758, 764

streq defined in line 581; never used
times85 defined in line 582; used 2 times

- in line 607-611(2)

word defined in line 573; used 17 times

- in line 604-616(11), 667, 706-713(4), 758

Last modified: 1988-09-09 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 3246 |