Annotation of researchv10no/cmd/btree/bundled, revision 1.1.1.1

1.1       root        1: # To unbundle, sh this file
                      2: echo be.h 1>&2
                      3: sed 's/.//' >be.h <<'//GO.SYSIN DD be.h'
                      4: -#define BERROR                100             /* first btree value of errno */
                      5: -#define BUTRAN                BERROR + 0      /* user caused tran abort */
                      6: -#define BNOWRITE      BERROR + 1      /* not opened for writing */
                      7: -#define BIOWRT                BERROR + 2      /* wrote short record */
                      8: -#define BNOMEM                BERROR + 3      /* no mem from malloc */
                      9: -#define BFATAL                BERROR + 4      /* last chance for user */
                     10: -#define BTALL         BERROR + 5      /* tree becoming taller than MXHT */
                     11: -#define BLASTE                BERROR + 6      /* one past last btree value of errno */
                     12: -extern int    errno;
                     13: -/*0101010011100100*/
                     14: //GO.SYSIN DD be.h
                     15: echo cbt.h 1>&2
                     16: sed 's/.//' >cbt.h <<'//GO.SYSIN DD cbt.h'
                     17: -#ifdef TEST
                     18: -#define NDSZ  64
                     19: -#else
                     20: -#define NDSZ 1024/* for real systems (larger may be slower) */
                     21: -#endif
                     22: -#define MAXKLEN       (NDSZ/4)-8
                     23: -#if MAXKLEN > 255
                     24: -#undef MAXKLEN
                     25: -#define MAXKLEN 255
                     26: -#endif
                     27: -#define MXHT  5
                     28: -typedef long ndaddr;
                     29: -/* for communication with users */
                     30: -typedef struct {
                     31: -      char *mdata;
                     32: -      unsigned short mlen;
                     33: -} mbuf;
                     34: -typedef struct bfile {
                     35: -      struct bfile *next;
                     36: -      struct hdr *path[MXHT + 1];
                     37: -      char height, advnc, rdwrt, flag[MXHT + 1];
                     38: -      ndaddr loc[MXHT + 1];
                     39: -      int tfd, dfd;
                     40: -      char *fname, *altname;
                     41: -      struct rdptr {
                     42: -              struct dkey *rptr;      /* current dkey */
                     43: -              short rnum;     /* its ordinal */
                     44: -              char rpref[MAXKLEN];    /* first dcom bytes of its key */
                     45: -      } rdptr;
                     46: -      char fatal;                     /* this bfile can't be used */
                     47: -} bfile;
                     48: -extern bfile *bopen();
                     49: -extern mbuf bkey();
                     50: -
                     51: -#define BERROR                100             /* first btree value of errno */
                     52: -#define BUTRAN                BERROR + 0      /* user caused tran abort */
                     53: -#define BNOWRITE      BERROR + 1      /* not opened for writing */
                     54: -#define BIOWRT                BERROR + 2      /* wrote short record */
                     55: -#define BNOMEM                BERROR + 3      /* no mem from malloc */
                     56: -#define BFATAL                BERROR + 4      /* last chance for user */
                     57: -#define BTALL         BERROR + 5      /* tree becoming taller than MXHT */
                     58: -#define BRDERR                BERROR + 6      /* read short record or read error */
                     59: -#define BLASTE                BERROR + 7      /* one past last btree value of errno */
                     60: -extern int    errno;
                     61: -
                     62: -/* users can ignore the rest of this stuff */
                     63: -/* keys in nodes */
                     64: -typedef struct dkey {
                     65: -      unsigned char dlen;     /* total size of structure */
                     66: -      char dcom;              /* bytes in common with preceding */
                     67: -      char dkey[MAXKLEN];     /* rest of key */
                     68: -} dkey;
                     69: -#define DKEYSZ        2       /* overhead in dkey */
                     70: -/* node header */
                     71: -typedef struct hdr {
                     72: -      long hstamp;    /* for owning process */
                     73: -      short kcnt;     /* keys in node */
                     74: -      char htype;
                     75: -      char hlev;
                     76: -} hdr;
                     77: -typedef struct {
                     78: -      short tfree;    /* free bytes in node, at end for triv checking */
                     79: -} trailer;
                     80: -#define nfree(p)      ((trailer *)((char *)(p) + NDSZ - sizeof(trailer)))->tfree
                     81: -#define SHARED        1
                     82: -#define INDEX 2
                     83: -#define READONLY      4
                     84: -#define bf_type(b, t) ((b)->path[0]->htype & (t))
                     85: -#define treeonly(b)   bf_type(b, INDEX)
                     86: -#define shared(b)     bf_type(b, SHARED)
                     87: -#define readonly(b)   bf_type(b, READONLY)
                     88: -/* disk addresses */
                     89: -typedef struct {
                     90: -      long lloc;
                     91: -      unsigned short llen;
                     92: -} lfaddr;
                     93: -#define ndadr(b, j)   ((ndaddr *)((char *)(b) + NDSZ - sizeof(trailer)) - (j) - 1)
                     94: -#define lfadr(b, j)   ((lfaddr *)((char *)(b) + NDSZ - sizeof(trailer)) - (j) - 1)
                     95: -#define mustwrite(bf, n)      bf->flag[n]     /* for getincore */
                     96: -/* node format:
                     97: - *    hdr, dkey, dkey, dkey, ..., space, adr, adrn, ..., adr0, trailer
                     98: - */
                     99: -extern int    bdump;                  /* dump on first fatal error */
                    100: -extern long   tranid, getlpid();      /* unique transaction id */
                    101: -#ifndef EOF
                    102: -#ifndef NULL
                    103: -#define NULL  0
                    104: -#endif
                    105: -#define EOF   -1
                    106: -#endif
                    107: -#define NOTFOUND      0
                    108: -#define FOUND         1
                    109: -
                    110: -#define alloc(x)      (x *)malloc(sizeof(x))
                    111: -#define stamped(b)    b->hstamp == tranid
                    112: -/*1000001111101111*/
                    113: //GO.SYSIN DD cbt.h
                    114: echo pr.h 1>&2
                    115: sed 's/.//' >pr.h <<'//GO.SYSIN DD pr.h'
                    116: -typedef struct {
                    117: -      short           match;  /* FOUND, NOTFOUND, or EOF */
                    118: -      unsigned char   ncom,   /* len of prefix in common with d */
                    119: -                      ocom;   /* len for predecessor of d */
                    120: -      dkey *d;                /* first key >= requested */
                    121: -                              /* or, if match==EOF, last in node */
                    122: -} private;
                    123: -/*0111110111010100*/
                    124: //GO.SYSIN DD pr.h
                    125: echo bdelete.c 1>&2
                    126: sed 's/.//' >bdelete.c <<'//GO.SYSIN DD bdelete.c'
                    127: -#include "cbt.h"
                    128: -#include "pr.h"
                    129: -
                    130: -extern bfile *curbf;
                    131: -bdelete(bf, key) bfile *bf; mbuf key;
                    132: -{     dkey *dold, *dnew;
                    133: -      hdr *b;
                    134: -      int svlen, dellen;
                    135: -      char *ffree;
                    136: -
                    137: -      if(bf == NULL)
                    138: -              return(EOF);
                    139: -      if(notran(bf))
                    140: -              return(EOF);
                    141: -      if(!bf->rdwrt) {
                    142: -              errno = BNOWRITE;
                    143: -              return(EOF);
                    144: -      }
                    145: -      if(bseek(bf, key) != FOUND)
                    146: -              return(NOTFOUND);
                    147: -      b = bf->path[0];
                    148: -      dold = bf->rdptr.rptr;
                    149: -      if(bf->rdptr.rnum + 1 >= b->kcnt) {
                    150: -              nfree(b) += dold->dlen + (treeonly(bf)? 0: sizeof(lfaddr));
                    151: -              --b->kcnt;
                    152: -              mustwrite(bf, 0) = 1;
                    153: -              if(b->hlev == 0 && b->kcnt <= 0 || b->hlev > 0 && b->kcnt < 0) {
                    154: -                      mustwrite(bf, 0) = 0;
                    155: -                      ndelete(1, key);
                    156: -              }
                    157: -              if(b->kcnt < 0)
                    158: -                      b->kcnt = 0;
                    159: -              (void) bseek(bf, key);
                    160: -              return(FOUND);
                    161: -      }
                    162: -
                    163: -      if(treeonly(bf))
                    164: -              ffree = (char *)&nfree(b) - nfree(b);
                    165: -      else
                    166: -              ffree = (char *)lfadr(b, b->kcnt - 1) - nfree(b);
                    167: -      svlen = dold->dlen;
                    168: -      dnew = (dkey *)((char *)dold + dold->dlen);
                    169: -      if(dnew->dcom <= dold->dcom) {
                    170: -              mvgbt((char *)dold, (char *)dnew, ffree - (char *)dnew);
                    171: -              if(!treeonly(bf))
                    172: -                      rmlfadr(b, bf->rdptr.rnum);
                    173: -              b->kcnt--;
                    174: -              mustwrite(bf, 0) = 1;
                    175: -              nfree(b) += svlen + (treeonly(bf)? 0: sizeof(lfaddr));
                    176: -              (void) bseek(bf, key);
                    177: -              return(FOUND);
                    178: -      }
                    179: -      dellen = dnew->dcom - dold->dcom;
                    180: -      /* writing over dold */
                    181: -      dold->dlen = dnew->dlen + dellen;
                    182: -      mvgbt(dold->dkey + dellen, dnew->dkey, ffree - dnew->dkey);
                    183: -      if(!treeonly(bf))
                    184: -              rmlfadr(b, bf->rdptr.rnum);
                    185: -      b->kcnt--;
                    186: -      mustwrite(bf, 0) = 1;
                    187: -      nfree(b) += svlen - dellen + (treeonly(bf)? 0: sizeof(lfaddr));
                    188: -      (void) bseek(bf, key);
                    189: -      return(FOUND);
                    190: -}
                    191: -rmlfadr(b, n) hdr *b; unsigned int n;
                    192: -{
                    193: -      mvgbt((char *)lfadr(b, b->kcnt - 2), (char *)lfadr(b, b->kcnt - 1),
                    194: -              (int)sizeof(lfaddr) * (b->kcnt - 1 - n));
                    195: -}
                    196: -rmndadr(b, n) hdr *b; unsigned short n;
                    197: -{
                    198: -      mvgbt((char *)ndadr(b, b->kcnt - 1), (char *)ndadr(b, b->kcnt),
                    199: -              (int)sizeof(ndaddr) * (b->kcnt - n));
                    200: -}
                    201: -ndelete(lev, key) mbuf key;
                    202: -{     hdr *b;
                    203: -      int svlen, dellen;
                    204: -      unsigned short n;
                    205: -      private x;
                    206: -      char *ffree;
                    207: -      dkey *dold, *dnew;
                    208: -      if(lev > curbf->height) {
                    209: -              b = curbf->path[curbf->height];
                    210: -              b->hlev = 0;
                    211: -              curbf->height = 0;
                    212: -              mustwrite(curbf, 0) = 1;
                    213: -              curbf->loc[0] = 0;
                    214: -              nfree(b) = NDSZ - sizeof(hdr) - sizeof(trailer);
                    215: -              b->kcnt = 0;
                    216: -              mvgbt((char *)curbf->path[0], (char *)b, NDSZ);
                    217: -              return;
                    218: -      }
                    219: -      b = curbf->path[lev];
                    220: -      n = xscan(b, key, &x);
                    221: -      if(x.match == EOF) {
                    222: -              if(b->kcnt <= 0) {
                    223: -                      mustwrite(curbf, lev) = 0;
                    224: -                      ndelete(lev+1, key);
                    225: -                      return;
                    226: -              }
                    227: -              b->kcnt--;
                    228: -              nfree(b) += sizeof(ndaddr) + x.d->dlen;
                    229: -              mustwrite(curbf, lev) = 1;
                    230: -              return;
                    231: -      }
                    232: -      dold = x.d;
                    233: -      dnew = (dkey *)((char *)dold + dold->dlen);
                    234: -      ffree = (char *)ndadr(b, b->kcnt) - nfree(b);
                    235: -      svlen = dold->dlen;
                    236: -      if(n + 1 >= b->kcnt || dnew->dcom <= dold->dcom) {
                    237: -              mvgbt((char *)dold, (char *)dnew, ffree - (char *)dnew);
                    238: -              rmndadr(b, n);
                    239: -              b->kcnt--;
                    240: -              mustwrite(curbf, lev) = 1;
                    241: -              nfree(b) += sizeof(ndaddr) + svlen;
                    242: -              return;
                    243: -      }
                    244: -      dellen = dnew->dcom - dold->dcom;
                    245: -      /* writing over dold */
                    246: -      dold->dlen = dnew->dlen + dellen;
                    247: -      mvgbt(dold->dkey + dellen, dnew->dkey, ffree - dnew->dkey);
                    248: -      rmndadr(b, n);
                    249: -      b->kcnt--;
                    250: -      mustwrite(curbf, lev) = 1;
                    251: -      nfree(b) += sizeof(ndaddr) + svlen - dellen;
                    252: -}
                    253: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bdelete.c\n"};
                    254: -/*1101110100011001*/
                    255: //GO.SYSIN DD bdelete.c
                    256: echo bt.c 1>&2
                    257: sed 's/.//' >bt.c <<'//GO.SYSIN DD bt.c'
                    258: -#include "cbt.h"
                    259: -#include "pr.h"
                    260: -
                    261: -bfile         *curbf;
                    262: -extern bfile  *newtran();
                    263: -extern char   *malloc(), *strcpy();
                    264: -extern long   lseek();
                    265: -
                    266: -bfile *bopen(s, typ) char *s; /* typ is 0 or 2 */
                    267: -{     bfile *p;
                    268: -      int n, i;
                    269: -
                    270: -      p = alloc(bfile);
                    271: -      if(p == NULL)
                    272: -              goto nomem;
                    273: -      n = strlen(s);
                    274: -      p->fname = malloc((unsigned)n + 3);
                    275: -      if(p->fname == NULL)
                    276: -              goto nomem;
                    277: -      (void) strcpy(p->fname, s);
                    278: -      strcpy(p->fname + n, ".T");
                    279: -      if((p->tfd = open(p->fname, typ)) == -1) {
                    280: -              free(p->fname);
                    281: -              free((char *)p);
                    282: -              return(NULL);
                    283: -      }
                    284: -      p->rdwrt = typ;
                    285: -      p->fatal = p->advnc = 0;
                    286: -      p->altname = NULL;
                    287: -      for(i = 0; i <= MXHT; i++) {
                    288: -              p->path[i] = NULL;
                    289: -              p->flag[i] = 0;
                    290: -              p->loc[i] = 0;
                    291: -      }
                    292: -      p->path[0] = (hdr *)malloc(NDSZ);
                    293: -      if(p->path[0] == NULL)
                    294: -              goto nomem;
                    295: -      curbf = p;
                    296: -      if(ndrd(0, (ndaddr)0) == EOF)
                    297: -              return(NULL);
                    298: -      strcpy(p->fname + n, ".F");
                    299: -      if(!treeonly(p) && (p->dfd = open(p->fname, typ)) == -1) {
                    300: -              (void) close(p->tfd);
                    301: -              free(p->fname);
                    302: -              free((char *) p->path[0]);
                    303: -              free((char *)p);
                    304: -              return(NULL);
                    305: -      }
                    306: -      else if(treeonly(p))
                    307: -              p->dfd = -1;
                    308: -      p->fname[n] = 0;
                    309: -      if(shared(p))
                    310: -              return(newtran(p));
                    311: -      else if(tranid == 0)
                    312: -              tranid = getlpid();
                    313: -      p->height = p->path[0]->hlev;
                    314: -      for(n = 1; n <= p->height; n++)
                    315: -              if((p->path[n] = (hdr *)malloc(NDSZ)) == NULL)
                    316: -                      goto nomem;
                    317: -      if(p->height > 0)
                    318: -              mvgbt((char *)p->path[p->height], (char *)p->path[0], NDSZ);
                    319: -      (void) bfirst(p);
                    320: -      return(p);
                    321: -nomem:
                    322: -      errno = BNOMEM;
                    323: -      return(NULL);
                    324: -}
                    325: -
                    326: -bseek(bf, key) bfile *bf; mbuf key;
                    327: -{     private m;
                    328: -      int i;
                    329: -      if(bf == NULL)
                    330: -              return(EOF);
                    331: -      if(notran(bf))
                    332: -              return(EOF);
                    333: -      if(!readonly(bf))
                    334: -              for(i = 0; i < bf->height; i++)
                    335: -                      if(mustwrite(bf, i))
                    336: -                              if(fixpath(bf) == EOF)
                    337: -                                      return(EOF);
                    338: -      bf->rdptr.rnum = desce(bf, key, &m);
                    339: -      if(bf->rdptr.rnum == EOF)
                    340: -              return(EOF);
                    341: -      bf->advnc = 0;
                    342: -      bf->rdptr.rptr = m.d;
                    343: -      if(m.match == EOF) {
                    344: -              if(advance() == EOF)
                    345: -                      return(EOF);
                    346: -              if(bf->rdptr.rptr != NULL)
                    347: -                      m.match = NOTFOUND;
                    348: -      }
                    349: -      if(m.match != EOF)
                    350: -              mvgbt(bf->rdptr.rpref, key.mdata, bf->rdptr.rptr->dcom);
                    351: -              /* maybe use rptr instead of m.d */
                    352: -      return(m.match);
                    353: -}
                    354: -
                    355: -bfirst(bf) bfile *bf;
                    356: -{     mbuf key;
                    357: -      key.mlen = 0;
                    358: -      return(bseek(bf, key));
                    359: -}
                    360: -
                    361: -bclose(bf) bfile *bf;
                    362: -{     int i;
                    363: -      if(bf == NULL)
                    364: -              return;
                    365: -      if(shared(bf)) {
                    366: -              if(intran())
                    367: -                      trabort();
                    368: -              rmtran(bf);
                    369: -      }
                    370: -      else
                    371: -              bflush(bf);
                    372: -      free(bf->fname);
                    373: -      for(i = 0; i <= MXHT; i++)
                    374: -              if(bf->path[i] != NULL)
                    375: -                      free((char *)bf->path[i]);
                    376: -      if(bf->tfd != -1)
                    377: -              (void) close(bf->tfd);
                    378: -      if(bf->dfd != -1)
                    379: -              (void) close(bf->dfd);
                    380: -      free((char *)bf);
                    381: -}
                    382: -
                    383: -bflush(bf) bfile *bf;
                    384: -{     int i;
                    385: -      if(bf == NULL)
                    386: -              return(0);
                    387: -      if(!bf->rdwrt) {
                    388: -              errno = BNOWRITE;
                    389: -              return(EOF);
                    390: -      }
                    391: -      curbf = bf;
                    392: -      if(shared(bf))
                    393: -              if(intran()) {
                    394: -                      trabort();
                    395: -                      return(EOF);
                    396: -              }
                    397: -              else return(0);
                    398: -      for(i = 0; i <= bf->height; i++) {
                    399: -              if(!mustwrite(bf, i))
                    400: -                      continue;
                    401: -              if(readonly(bf) || i == bf->height)
                    402: -                      if(ndwrt(bf->path[i], bf->loc[i]) == EOF)
                    403: -                              return(EOF);
                    404: -              else
                    405: -                      if(fixpath(bf) == EOF)
                    406: -                              return(EOF);
                    407: -              bf->flag[i] = 0;
                    408: -      }
                    409: -      return(0);
                    410: -}
                    411: -
                    412: -breclen(bf) bfile *bf;
                    413: -{
                    414: -      if(bf == NULL)
                    415: -              return(EOF);
                    416: -      if(notran(bf))
                    417: -              return(EOF);
                    418: -      if(bf->advnc)
                    419: -              if(advance() == EOF)
                    420: -                      return(EOF);
                    421: -      if(bf->rdptr.rnum >= bf->path[0]->kcnt)
                    422: -              return(EOF);
                    423: -      if(treeonly(bf))
                    424: -              return(0);
                    425: -      return(lfadr(bf->path[0], bf->rdptr.rnum)->llen);
                    426: -}
                    427: -
                    428: -mbuf bkey(bf) bfile *bf;
                    429: -{     mbuf x;
                    430: -      dkey *d;
                    431: -      if(bf == NULL)
                    432: -              goto eof;
                    433: -      if(notran(bf))
                    434: -              goto eof;
                    435: -      if(bf->advnc)
                    436: -              if(advance() == EOF)
                    437: -                      goto eof;
                    438: -      if(bf->rdptr.rnum >= bf->path[0]->kcnt)
                    439: -              goto eof;
                    440: -      d = bf->rdptr.rptr;
                    441: -      x.mlen = d->dlen - DKEYSZ + d->dcom;
                    442: -      mvgbt(bf->rdptr.rpref + d->dcom, d->dkey, d->dlen-DKEYSZ);
                    443: -      x.mdata = bf->rdptr.rpref;
                    444: -      return(x);
                    445: -eof:
                    446: -      x.mlen = 0;
                    447: -      x.mdata = NULL;
                    448: -      return(x);
                    449: -}
                    450: -
                    451: -bread(bf, key, rec) bfile *bf; mbuf *key, *rec;
                    452: -{
                    453: -      dkey *d;
                    454: -      lfaddr *x;
                    455: -      int n;
                    456: -      if(bf == NULL)
                    457: -              return(NULL);
                    458: -      if(notran(bf))
                    459: -              return(EOF);
                    460: -      if(bf->advnc)
                    461: -              if(advance() == EOF)
                    462: -                      return(EOF);
                    463: -      if(bf->rdptr.rnum >= bf->path[0]->kcnt)
                    464: -              return(EOF);
                    465: -      if(key != NULL) {
                    466: -              d = bf->rdptr.rptr;
                    467: -              key->mlen = d->dlen - DKEYSZ + d->dcom;
                    468: -              mvgbt(key->mdata, bf->rdptr.rpref, d->dcom);
                    469: -              mvgbt(key->mdata + d->dcom, d->dkey, d->dlen - DKEYSZ);
                    470: -      }
                    471: -      if(rec != NULL && !treeonly(bf)) {
                    472: -              x = lfadr(bf->path[0], bf->rdptr.rnum);
                    473: -              rec->mlen = x->llen;
                    474: -              if(rec->mlen != 0) {
                    475: -                      (void) lseek(bf->dfd, x->lloc, 0);
                    476: -                      if((n = read(bf->dfd, rec->mdata, (int)rec->mlen))
                    477: -                              != rec->mlen) {
                    478: -                              if(n >= 0)
                    479: -                                      errno = BRDERR;
                    480: -                              return(EOF);
                    481: -                      }
                    482: -              }
                    483: -      }
                    484: -      bf->advnc = 1;
                    485: -      return(0);
                    486: -}
                    487: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bt.c\n"};
                    488: -/*0001011110110101*/
                    489: //GO.SYSIN DD bt.c
                    490: echo btadd.c 1>&2
                    491: sed 's/.//' >btadd.c <<'//GO.SYSIN DD btadd.c'
                    492: -#include "stdio.h"
                    493: -#include "cbt.h"
                    494: -
                    495: -/* like btbuild, but random access */
                    496: -char keybuf[NDSZ];
                    497: -char recbuf[32767];
                    498: -mbuf key = { keybuf, 0};
                    499: -mbuf rec = { recbuf, 0};
                    500: -bfile *bf;
                    501: -int cflag;
                    502: -
                    503: -main(argc, argv)
                    504: -char **argv;
                    505: -{     int n;
                    506: -      if(argv[1][0] == '-') {
                    507: -              cflag++;
                    508: -              argc--;
                    509: -              argv++;
                    510: -      }
                    511: -      if(argc != 2) {
                    512: -              fprintf(stderr, "usage: btadd bfile < recs\n");
                    513: -              exit(1);
                    514: -      }
                    515: -      if((bf = bopen(argv[1], 2)) == NULL) {
                    516: -              perror(argv[1]);
                    517: -              exit(1);
                    518: -      }
                    519: -      for(;;) {
                    520: -              get(2, (char *)&key.mlen);
                    521: -              if(key.mlen > MAXKLEN) {
                    522: -                      fprintf(stderr, "key too long\n");
                    523: -                      exit(1);
                    524: -              }
                    525: -              get(key.mlen, key.mdata);
                    526: -              get(2, (char *)&rec.mlen);
                    527: -              if(rec.mlen > sizeof(recbuf)) {
                    528: -                      fprintf(stderr, "rec len %ud: recompile btadd\n",
                    529: -                              rec.mlen);
                    530: -                      abort();
                    531: -              }
                    532: -              get(rec.mlen, rec.mdata);
                    533: -              (void)bwrite(bf, key, rec);
                    534: -              bfirst(bf);
                    535: -              if(bseek(bf, key) != FOUND) {
                    536: -                      key.mdata[key.mlen] = 0;
                    537: -                      fprintf(stderr, "vanished:%s:\n", key.mdata);
                    538: -                      abort();
                    539: -              }
                    540: -              if(cflag)
                    541: -                      bcheck(bf);
                    542: -      }
                    543: -}
                    544: -get(n, s)
                    545: -char *s;
                    546: -{     int m;
                    547: -      for(m = 0; n > 0; n -= m) {
                    548: -              m = read(0, s, n);
                    549: -              if(m == 0) {
                    550: -                      bclose(bf);
                    551: -                      exit(0);
                    552: -              }
                    553: -              if(m < 0) {
                    554: -                      fprintf(stderr, "io error in btadd\n");
                    555: -                      abort();
                    556: -              }
                    557: -              s += m;
                    558: -      }
                    559: -}
                    560: -
                    561: -mbuf new, old;
                    562: -char newbuf[NDSZ], oldbuf[NDSZ];
                    563: -bcheck(bf)
                    564: -bfile *bf;
                    565: -{     long i;
                    566: -      int j, k;
                    567: -      char *p;
                    568: -      bfirst(bf);
                    569: -      new.mdata = newbuf;
                    570: -      old.mdata = oldbuf;
                    571: -      for(i = 0;; i++) {
                    572: -              if(bread(bf, &new, (mbuf *)NULL) == EOF)
                    573: -                      break;
                    574: -              if(i > 0) {
                    575: -                      k = new.mlen;
                    576: -                      if(old.mlen < new.mlen)
                    577: -                              k = old.mlen;
                    578: -                      for(j = 0; j < k; j++)
                    579: -                              if(new.mdata[j] != old.mdata[j])
                    580: -                                      break;
                    581: -                      if(j != k) {
                    582: -                              if(new.mdata[j] > old.mdata[j])
                    583: -                                      continue;
                    584: -bad:
                    585: -                              fprintf(stderr, "disorder at key %ld\n", i);
                    586: -                              key.mdata[key.mlen] = 0;
                    587: -                              fprintf(stderr, "key is:%s:\n", key.mdata);
                    588: -                              abort();
                    589: -                      }
                    590: -                      if(old.mlen >= new.mlen)
                    591: -                              goto bad;
                    592: -              }
                    593: -              p = old.mdata;
                    594: -              old = new;
                    595: -              new.mdata = p;
                    596: -      }
                    597: -}
                    598: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/25:btadd.c\n"};
                    599: -/*1100001100101101*/
                    600: //GO.SYSIN DD btadd.c
                    601: echo btbuild.c 1>&2
                    602: sed 's/.//' >btbuild.c <<'//GO.SYSIN DD btbuild.c'
                    603: -#include "stdio.h"
                    604: -#include "cbt.h"
                    605: -#define SZ    MXHT+1
                    606: -
                    607: -typedef struct {
                    608: -      unsigned short mlen;
                    609: -      char mdata[NDSZ];       /* max size of values */
                    610: -} xbuf;
                    611: -int address[SZ];      /* where the next address goes in the node */
                    612: -xbuf curkey[SZ];      /* last key put in the node */
                    613: -xbuf shortone;                /* for compression */
                    614: -int freecnt[SZ];              /* number of bytes left in node */
                    615: -dkey *kp[SZ];         /* where to put next dkey in node */
                    616: -char node[SZ][NDSZ];  /* the nodes */
                    617: -char used[SZ+1];      /* which nodes have been used */
                    618: -xbuf nkey;            /* as read by getrec */
                    619: -struct {
                    620: -      unsigned short mlen;
                    621: -      char mdata[32767];
                    622: -} val;
                    623: -lfaddr currec;                /* where getrec put val */
                    624: -FILE *tfd, *dfd;
                    625: -char name[16];
                    626: -int type;
                    627: -long reccnt;
                    628: -extern char *malloc();
                    629: -
                    630: -char *
                    631: -prkey(a)
                    632: -xbuf *a;
                    633: -{     int i;
                    634: -      unsigned char c;
                    635: -      static char buf[4*NDSZ], *p;
                    636: -      for(i = 0, p = buf; i < a->mlen; i++) {
                    637: -              c = a->mdata[i];
                    638: -              if(c < ' ') {
                    639: -                      *p++ = '^';
                    640: -                      c += ' ';
                    641: -              }
                    642: -              if(c < 127)
                    643: -                      *p++ = (char)c;
                    644: -              else {
                    645: -                      *p++ = '\\';
                    646: -                      *p++ = (c >> 6) + '0';
                    647: -                      *p++ = ((c&63)>>3) + '0';
                    648: -                      *p++ = c&7 + '0';
                    649: -              }
                    650: -      }
                    651: -      *p++ = 0;
                    652: -      return(buf);
                    653: -}
                    654: -pref(a, b, lev) xbuf *a, *b;
                    655: -{     register int n;
                    656: -      register char *p, *q;
                    657: -      for(n = 0, p = a->mdata, q = b->mdata; n < a->mlen && n < b->mlen; n++)
                    658: -              if(*p++ != *q++)
                    659: -                      break;
                    660: -      p--, q--;
                    661: -      if(lev == 0 && ((n == b->mlen && n >= a->mlen) || *p > *q)) {
                    662: -              fprintf(stderr, "key %ld out of order:\n", reccnt);
                    663: -              fprintf(stderr, "key %ld is %s\n", reccnt - 1, prkey(a));
                    664: -              fprintf(stderr, "key %ld is %s\n", reccnt, prkey(b));
                    665: -      }
                    666: -      return(n);
                    667: -}
                    668: -
                    669: -getrec()
                    670: -{
                    671: -      reccnt++;
                    672: -      if(mget(&nkey))
                    673: -              return(-1);
                    674: -      if(mget((xbuf *)&val))
                    675: -              fail("half a record read");
                    676: -      if((currec.llen = val.mlen) != 0) {
                    677: -              currec.lloc = ftell(dfd);
                    678: -              (void) fwrite(val.mdata, 1, val.mlen, dfd);
                    679: -              if(ferror(dfd))
                    680: -                      fail("value write");
                    681: -      }
                    682: -      else currec.lloc = 0;
                    683: -      return(1);
                    684: -}
                    685: -
                    686: -mget(a) xbuf *a;
                    687: -{
                    688: -      (void) fread((char *)&(a->mlen), 1, sizeof(a->mlen), stdin);
                    689: -      if(feof(stdin) || ferror(stdin))
                    690: -              return(1);
                    691: -      if(fread(a->mdata, 1, a->mlen, stdin) != a->mlen)
                    692: -              return(1);
                    693: -      return(0);
                    694: -}
                    695: -
                    696: -ndaddr ndwrt(level)
                    697: -{     ndaddr loc;
                    698: -      int i;
                    699: -      hdr *x;
                    700: -      trailer *t;
                    701: -      loc = ftell(tfd)/NDSZ;
                    702: -      x = (hdr *)(node[level]);
                    703: -      x->hlev = level;
                    704: -      t = (trailer *)(node[level] + NDSZ - sizeof(trailer));
                    705: -      t->tfree = freecnt[level];
                    706: -      x->kcnt = address[level] - (level == 0? 0: 1);
                    707: -      x->htype = type;
                    708: -      (void) fwrite(node[level], 1, NDSZ, tfd);
                    709: -      if(ferror(tfd))
                    710: -              fail("node write");
                    711: -      for(i = 0; i < NDSZ; i++)
                    712: -              node[level][i] = 0;
                    713: -      address[level] = 0;
                    714: -      curkey[level].mlen = 0;
                    715: -      freecnt[level] = NDSZ - sizeof(hdr) - sizeof(trailer);
                    716: -      if(level)
                    717: -              freecnt[level] -= sizeof(ndaddr);
                    718: -      kp[level] = (dkey *)(node[level] + sizeof(hdr));
                    719: -      return(loc);
                    720: -}
                    721: -
                    722: -finish(level, ptr) ndaddr ptr;
                    723: -{     ndaddr loc;
                    724: -      if(!used[level])
                    725: -              return;
                    726: -      *ndadr(node[level], address[level]++) = ptr;
                    727: -      if(!used[level + 1])
                    728: -              fseek(tfd, 0L, 0);
                    729: -      loc = ndwrt(level);
                    730: -      finish(level + 1, loc);
                    731: -}
                    732: -
                    733: -insert(level, key, ptr) xbuf *key; ndaddr ptr;
                    734: -{     int n, len;
                    735: -      char *p;
                    736: -      ndaddr loc;
                    737: -      used[level] = 1;
                    738: -      n = pref(&curkey[level], key, level);
                    739: -      len = DKEYSZ + key->mlen - n + sizeof(ptr);
                    740: -      if(len < freecnt[level]) {
                    741: -              *ndadr(node[level], address[level]++) = ptr;
                    742: -              kp[level]->dlen = len - sizeof(ptr);
                    743: -              kp[level]->dcom = n;
                    744: -              mvgbt(kp[level]->dkey, key->mdata + n, key->mlen - n);
                    745: -              p = (char *)(kp[level]) + kp[level]->dlen;
                    746: -              kp[level] = (dkey *)p;
                    747: -              freecnt[level] -= len;
                    748: -              curkey[level] = *key;
                    749: -      }
                    750: -      else {
                    751: -              *ndadr(node[level],address[level]++) = ptr;
                    752: -              loc = ndwrt(level);
                    753: -              insert(level+1, key, loc);
                    754: -              curkey[level].mlen = 0;
                    755: -      }
                    756: -}
                    757: -
                    758: -doit()
                    759: -{     int n, len;
                    760: -      ndaddr loc;
                    761: -      char *p;
                    762: -      for(;;) {
                    763: -              if(getrec() == -1)
                    764: -                      break;
                    765: -              used[0] = 1;
                    766: -              n = pref(&curkey[0], &nkey, 0);
                    767: -              len = DKEYSZ + nkey.mlen - n + sizeof(currec);
                    768: -              if(type & INDEX)
                    769: -                      len -= sizeof(currec);
                    770: -              if(len < freecnt[0]) {
                    771: -                      freecnt[0] -= len;
                    772: -                      if(!(type & INDEX))
                    773: -                              *lfadr(node[0], address[0]++) = currec;
                    774: -                      else
                    775: -                              address[0]++;
                    776: -                      kp[0]->dlen = DKEYSZ + nkey.mlen - n;
                    777: -                      kp[0]->dcom = n;
                    778: -                      mvgbt(kp[0]->dkey, nkey.mdata + n, nkey.mlen - n);
                    779: -                      p = (char *)(kp[0]) + kp[0]->dlen;
                    780: -                      kp[0] = (dkey *)p;
                    781: -                      curkey[0] = nkey;
                    782: -              }
                    783: -              else {
                    784: -                      shortest(&curkey[0], &nkey);
                    785: -                      loc = ndwrt(0);
                    786: -                      freecnt[0] -= DKEYSZ + nkey.mlen + sizeof(currec);
                    787: -                      if(type & INDEX)
                    788: -                              freecnt[0] += sizeof(currec);
                    789: -                      insert(1, &shortone, loc);
                    790: -                      if(!(type & INDEX))
                    791: -                              *lfadr(node[0], address[0]++) = currec;
                    792: -                      else
                    793: -                              address[0]++;
                    794: -                      kp[0]->dlen = DKEYSZ + nkey.mlen;
                    795: -                      kp[0]->dcom = 0;
                    796: -                      mvgbt(kp[0]->dkey, nkey.mdata, nkey.mlen);
                    797: -                      p = (char *)(kp[0]) + kp[0]->dlen;
                    798: -                      kp[0] = (dkey *)p;
                    799: -                      curkey[0] = nkey;
                    800: -              }
                    801: -      }
                    802: -      if(!used[1])
                    803: -              (void) fseek(tfd, 0L, 0);
                    804: -      loc = ndwrt(0);
                    805: -      finish(1, loc);
                    806: -}
                    807: -
                    808: -init(s)
                    809: -char *s;
                    810: -{     int i;
                    811: -      hdr *b;
                    812: -      char xx[NDSZ];
                    813: -      (void) sprintf(name, "%s.T", s);
                    814: -      tfd = fopen(name, "r");
                    815: -      if(tfd == NULL) {
                    816: -              perror(s);
                    817: -              exit(1);
                    818: -      }
                    819: -      fread(xx, 1, NDSZ, tfd);
                    820: -      fclose(tfd);
                    821: -      tfd = fopen(name, "w");
                    822: -      (void) fseek(tfd, (long)NDSZ, 0);
                    823: -      b = (hdr *)xx;
                    824: -      type = b->htype;
                    825: -      (void) sprintf(name, "%s.F", s);
                    826: -      if((type & INDEX) != INDEX)
                    827: -              dfd = fopen(name, "w");
                    828: -      for(i = 0; i < SZ; i++) {
                    829: -              freecnt[i] = NDSZ - sizeof(hdr) - sizeof(trailer);
                    830: -              if(i)
                    831: -                      freecnt[i] -= sizeof(ndaddr);
                    832: -              kp[i] = (dkey *)(node[i] + sizeof(hdr));
                    833: -      }
                    834: -}
                    835: -
                    836: -main(argc, argv)
                    837: -char **argv;
                    838: -{
                    839: -      if(argc != 2) {
                    840: -              fprintf(stderr, "%s: too many arguments\n", argv[1]);
                    841: -              exit(1);
                    842: -      }
                    843: -      init(argv[1]);
                    844: -      doit();
                    845: -      exit(0);
                    846: -}
                    847: -
                    848: -shortest(a, b) xbuf *a, *b;
                    849: -{     int n;
                    850: -      char *p, *q, *s;
                    851: -      p = a->mdata;
                    852: -      q = b->mdata;
                    853: -      s = shortone.mdata;
                    854: -      for(n = 0; n < a->mlen && n < b->mlen; n++, p++, q++)
                    855: -              if(*p == *q)
                    856: -                      *s++ = *p;
                    857: -              else break;
                    858: -      if(n < a->mlen) {
                    859: -      again:
                    860: -              if(n + 1 == a->mlen)
                    861: -                      *s++ = *p;
                    862: -              else if(*p + 1 < *q)
                    863: -                      *s++ = *p + 1;
                    864: -              else {
                    865: -                      *s++ = *p++;
                    866: -                      n++;
                    867: -                      if(*p + 1 > *p)
                    868: -                              *s++ = *p + 1;
                    869: -                      else goto again;
                    870: -              }
                    871: -      }
                    872: -      shortone.mlen = s - shortone.mdata;
                    873: -}
                    874: -prbuf(x) xbuf *x;
                    875: -{     int i;
                    876: -      for(i = 0; i < x->mlen; i++)
                    877: -              printf("%3.3o ", x->mdata[i]);
                    878: -      putchar('\n');
                    879: -}
                    880: -fail(s)
                    881: -char *s;
                    882: -{
                    883: -      perror(s);
                    884: -      exit(2);
                    885: -}
                    886: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:btbuild.c\n"};
                    887: -/*1101000110100100*/
                    888: //GO.SYSIN DD btbuild.c
                    889: echo btcat.c 1>&2
                    890: sed 's/.//' >btcat.c <<'//GO.SYSIN DD btcat.c'
                    891: -#include "stdio.h"
                    892: -#include "cbt.h"
                    893: -extern char *malloc(), *realloc();
                    894: -extern mbuf bkey();
                    895: -extern bfile *bopen();
                    896: -int rflag;
                    897: -int rsize = 64;
                    898: -mbuf key, rec;
                    899: -char tabchar = '\t';
                    900: -main(argc, argv) char **argv;
                    901: -{
                    902: -      rec.mdata = malloc(rsize);
                    903: -      key.mdata = malloc(NDSZ);
                    904: -      for(argc--, argv++; argc > 0; argc--, argv++) {
                    905: -              switch(*argv[0]) {
                    906: -              case '-':
                    907: -                      if(argv[0][1] == 'R')
                    908: -                              rflag = 1;
                    909: -                      else fprintf(stderr, "unknown option %s\n", argv[0]);
                    910: -                      break;
                    911: -              default:
                    912: -                      copy(argv[0]);
                    913: -                      break;
                    914: -              }
                    915: -      }
                    916: -      exit(0);
                    917: -}
                    918: -copy(s) char *s;
                    919: -{     bfile *bt;
                    920: -      int n;
                    921: -      bt = bopen(s, 0);
                    922: -      if(bt == NULL) {
                    923: -              perror(s);
                    924: -              exit(1);
                    925: -      }
                    926: -      if(bfirst(bt) == EOF) {
                    927: -              fprintf(stderr, "%s empty\n", s);
                    928: -              return;
                    929: -      }
                    930: -      while((n = breclen(bt)) != EOF) {
                    931: -              if(n > rsize) {
                    932: -                      rsize = n;
                    933: -                      rec.mdata = realloc(rec.mdata, rsize);
                    934: -              }
                    935: -              (void) bread(bt, &key, &rec);
                    936: -              if(!rflag) {
                    937: -                      out(key);
                    938: -                      putchar(tabchar);
                    939: -                      out(rec);
                    940: -                      putchar('\n');
                    941: -              }
                    942: -              else {
                    943: -                      fwrite((char *)&key.mlen, 1, sizeof(short), stdout);
                    944: -                      fwrite(key.mdata, key.mlen, 1, stdout);
                    945: -                      fwrite((char *)&rec.mlen, 1, sizeof(short), stdout);
                    946: -                      fwrite(rec.mdata, rec.mlen, 1, stdout);
                    947: -              }
                    948: -                      
                    949: -      }
                    950: -      bclose(bt);
                    951: -}
                    952: -out(a) mbuf a;
                    953: -{     int i;
                    954: -      for(i = 0; i < a.mlen; i++) putchar(*(a.mdata + i));
                    955: -}
                    956: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/4/8:btcat.c\n"};
                    957: -/*1110000011011001*/
                    958: //GO.SYSIN DD btcat.c
                    959: echo btcreat.c 1>&2
                    960: sed 's/.//' >btcreat.c <<'//GO.SYSIN DD btcreat.c'
                    961: -#include "stdio.h"
                    962: -#include "cbt.h"
                    963: -#define error(x, y) {fprintf(stderr, x, y); exit(1); }
                    964: -
                    965: -int iflag, rflag;
                    966: -char node[NDSZ];
                    967: -char buf[512];
                    968: -extern char *malloc();
                    969: -
                    970: -main(argc, argv)
                    971: -char **argv;
                    972: -{     int i, fd;
                    973: -      hdr *b;
                    974: -      char *p;
                    975: -      for(i = 1; i < argc; i++) {
                    976: -              if(argv[i][0] == '-') {
                    977: -                      for(p = argv[i] + 1; *p; p++)
                    978: -                              if(*p == 'i')
                    979: -                                      iflag = 1;
                    980: -                              else if(*p == 'r')
                    981: -                                      rflag = 1;
                    982: -                              else
                    983: -                                      error("unknown flag %c\n", *p);
                    984: -                      if(i >= argc - 1)
                    985: -                              error("file name?", 0);
                    986: -                      continue;
                    987: -              }
                    988: -              if(!iflag) {
                    989: -                      sprintf(buf, "%s.F", argv[i]);
                    990: -                      if((fd = creat(buf, 0666)) < 0) {
                    991: -                              perror(buf);
                    992: -                              exit(1);
                    993: -                      }
                    994: -                      close(fd);
                    995: -              }
                    996: -              sprintf(buf, "%s.T", argv[i]);
                    997: -              if((fd = creat(buf, 0666)) < 0) {
                    998: -                      perror(buf);
                    999: -                      if(!iflag) {
                   1000: -                              sprintf(buf, "%s.F", argv[i]);
                   1001: -                              unlink(buf);
                   1002: -                      }
                   1003: -                      exit(1);
                   1004: -              }
                   1005: -              b = (hdr *)node;
                   1006: -              b->kcnt = 0;
                   1007: -              if(iflag)
                   1008: -                      b->htype |= INDEX;
                   1009: -              if(rflag)
                   1010: -                      b->htype |= READONLY;
                   1011: -              nfree(b) = NDSZ - sizeof(hdr) - sizeof(trailer);
                   1012: -              if(write(fd, node, NDSZ) != NDSZ)
                   1013: -                      perror("failed");
                   1014: -              close(fd);
                   1015: -      }
                   1016: -      exit(0);
                   1017: -}
                   1018: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:btcreat.c\n"};
                   1019: -/*0011011101111110*/
                   1020: //GO.SYSIN DD btcreat.c
                   1021: echo btdelete.c 1>&2
                   1022: sed 's/.//' >btdelete.c <<'//GO.SYSIN DD btdelete.c'
                   1023: -/* read keys from stdin, and delete the records from argv[1] */
                   1024: -#include "stdio.h"
                   1025: -#include "cbt.h"
                   1026: -
                   1027: -char buf[NDSZ];
                   1028: -bfile *bf;
                   1029: -mbuf key;
                   1030: -
                   1031: -main(argc, argv)
                   1032: -char **argv;
                   1033: -{     char *p;
                   1034: -      int c = 0;
                   1035: -      if(argc != 2) {
                   1036: -              fprintf(stderr, "usage: delete b-tree < keys\n");
                   1037: -              exit(1);
                   1038: -      }
                   1039: -      if((bf = bopen(argv[1], 2)) == NULL) {
                   1040: -              perror(argv[1]);
                   1041: -              exit(1);
                   1042: -      }
                   1043: -      key.mdata = buf;
                   1044: -loop:
                   1045: -      if(c == EOF) {
                   1046: -              bclose(bf);
                   1047: -              exit(0);
                   1048: -      }
                   1049: -      for(p = buf; (c = getchar()) != '\n' && c != EOF; *p++ = c)
                   1050: -              ;
                   1051: -      *p = 0;
                   1052: -      key.mlen = p - buf;
                   1053: -      if(key.mlen == 0)
                   1054: -              goto loop;
                   1055: -      if(!bdelete(bf, key))
                   1056: -              fprintf(stderr, "not in file:%s\n", buf);
                   1057: -      goto loop;
                   1058: -}
                   1059: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:btdelete.c\n"};
                   1060: -/*0010110100010101*/
                   1061: //GO.SYSIN DD btdelete.c
                   1062: echo btdiag.c 1>&2
                   1063: sed 's/.//' >btdiag.c <<'//GO.SYSIN DD btdiag.c'
                   1064: -#include "stdio.h"
                   1065: -#include "cbt.h"
                   1066: -#include "sys/types.h"
                   1067: -#include "sys/stat.h"
                   1068: -
                   1069: -extern bfile *bopen();
                   1070: -extern char *malloc();
                   1071: -extern int errno;
                   1072: -int errcnt;
                   1073: -char nodes[MXHT + 1][NDSZ];
                   1074: -int loc[MXHT + 1];
                   1075: -char *seen;
                   1076: -dkey *curd[MXHT + 1];
                   1077: -char curkey[MXHT + 1][MAXKLEN];
                   1078: -int keynum[MXHT + 1];
                   1079: -mbuf tinykey = { "", 0};
                   1080: -mbuf giantkey = {"\177\177\177\177", 4};
                   1081: -
                   1082: -main(argc, argv)
                   1083: -char **argv;
                   1084: -{     bfile *bt;
                   1085: -      int n;
                   1086: -      if(argc < 2)
                   1087: -              error("file name?");
                   1088: -      bt = bopen(argv[1], 0);
                   1089: -      if(bt == 0)
                   1090: -              error("couldn't open tree");
                   1091: -      n = diagnose(bt);
                   1092: -      printf("return value is %d\n", n);
                   1093: -      exit(n);
                   1094: -}
                   1095: -
                   1096: -diagnose(b)
                   1097: -bfile *b;
                   1098: -{     int i;
                   1099: -      struct stat statb;
                   1100: -      if(fstat(b->tfd, &statb) < 0)
                   1101: -              error("can't stat tree");
                   1102: -      if(statb.st_size % NDSZ || statb.st_size <= 0) {
                   1103: -              printf("tree size %d mod ndsz %d != 0\n", statb.st_size, NDSZ);
                   1104: -              errcnt++;
                   1105: -      }
                   1106: -      if(b->height > MXHT || b->height < 0) {
                   1107: -              printf("tree height %d weird max %d\n", b->height, MXHT);
                   1108: -              return(-1);
                   1109: -      }
                   1110: -      seen = malloc(statb.st_size / NDSZ);
                   1111: -      for(i = 0; i < statb.st_size/NDSZ; i++)
                   1112: -              seen[i] = -1;
                   1113: -      lseek(b->tfd, 0, 0);
                   1114: -      if((i = read(b->tfd, nodes[b->height], NDSZ)) != NDSZ) {
                   1115: -              printf("read of root returned %d (%d)\n", i, errno);
                   1116: -              error("can't proceed");
                   1117: -      }
                   1118: -      return(dolevel(b->tfd, b->height, tinykey, giantkey) || errcnt);
                   1119: -}
                   1120: -
                   1121: -mbuf
                   1122: -firstkey(n)
                   1123: -{     hdr *b;
                   1124: -      mbuf z;
                   1125: -      int i;
                   1126: -      b = (hdr *)nodes[n];
                   1127: -      keynum[n] = 0;
                   1128: -      if(keynum[n] >= b->kcnt) {
                   1129: -              z.mlen = -1;
                   1130: -              return(z);
                   1131: -      }
                   1132: -      curd[n] = (dkey *)(b+1);
                   1133: -      for(i = 0; i < curd[n]->dlen - DKEYSZ; i++)
                   1134: -              curkey[n][i] = curd[n]->dkey[i];
                   1135: -      z.mlen = i;
                   1136: -      z.mdata = curkey[n];
                   1137: -      return(z);
                   1138: -}
                   1139: -
                   1140: -mbuf
                   1141: -nextkey(n)
                   1142: -{     mbuf z;
                   1143: -      char *p = (char *)curd[n];
                   1144: -      dkey *d;
                   1145: -      int i;
                   1146: -      hdr *b = (hdr *)nodes[n];
                   1147: -      if(++keynum[n] >= b->kcnt) {
                   1148: -              z.mlen = -1;
                   1149: -              return(z);
                   1150: -      }
                   1151: -      p += curd[n]->dlen;
                   1152: -      d = curd[n] = (dkey *)p;
                   1153: -      z.mdata = curkey[n];
                   1154: -      for(i = 0; i < d->dlen - DKEYSZ; i++)
                   1155: -              z.mdata[d->dcom + i] = d->dkey[i];
                   1156: -      z.mlen = i + d->dcom;
                   1157: -      return(z);
                   1158: -}
                   1159: -
                   1160: -dolevel(fd, lev, lokey, hikey)
                   1161: -mbuf lokey, hikey;
                   1162: -{     int i, j;
                   1163: -      mbuf left, right;
                   1164: -      char leftx[MAXKLEN];
                   1165: -      hdr *b = (hdr *)nodes[lev];
                   1166: -      if(lseek(fd, loc[lev] * NDSZ, 0) < 0 || read(fd, nodes[lev], NDSZ) != NDSZ) {
                   1167: -              printf("couldn't read node %d, level %d\n", loc[lev], lev);
                   1168: -              return(-1);
                   1169: -      }
                   1170: -      if(seen[loc[lev]] != -1) {
                   1171: -              printf("node %d visited twice, at lev %d and %d\n", lev, seen[loc[lev]], lev);
                   1172: -              if(lev != seen[loc[lev]])
                   1173: -                      return(-1);
                   1174: -      }
                   1175: -      else
                   1176: -              seen[loc[lev]] = lev;
                   1177: -      if(check(loc[lev], nodes[lev], lokey, hikey))
                   1178: -              return(-1);
                   1179: -      if(lev == 0)
                   1180: -              return(0);
                   1181: -      right = firstkey(lev);
                   1182: -      left.mlen = lokey.mlen;
                   1183: -      left.mdata = leftx;
                   1184: -      for(j = 0; j < left.mlen; j++)
                   1185: -              left.mdata[j] = lokey.mdata[j];
                   1186: -      for(i = 0; i < b->kcnt; i++) {
                   1187: -              loc[lev - 1] = *ndadr(b, i);
                   1188: -              if(dolevel(fd, lev - 1, left, right))
                   1189: -                      return(-1);
                   1190: -              left.mlen = right.mlen;
                   1191: -              for(j = 0; j < left.mlen; j++)
                   1192: -                      left.mdata[j] = right.mdata[j];
                   1193: -              right = nextkey(lev);
                   1194: -              if(right.mlen < 0)
                   1195: -                      printf("unexpected end of keys, node %d\n", loc[lev]);
                   1196: -      }
                   1197: -      loc[lev - 1] = *ndadr(b, i);
                   1198: -      return(dolevel(fd, lev - 1, left, hikey));
                   1199: -}
                   1200: -
                   1201: -check(noden, b, lokey, hikey)
                   1202: -hdr *b;
                   1203: -mbuf lokey, hikey;
                   1204: -{     int i, plen, sz, j;
                   1205: -      char *p, prefix[MAXKLEN];
                   1206: -      dkey *d;
                   1207: -
                   1208: -      /* check space allocation */
                   1209: -      sz = sizeof(hdr) + sizeof(trailer) + nfree(b);
                   1210: -      if(nfree(b) < 0) {
                   1211: -              printf("nfree: %d < 0, node %d\n", nfree(b), noden);
                   1212: -              errcnt++;
                   1213: -      }
                   1214: -      if(sz > NDSZ) {
                   1215: -              printf("nfree: %d impossibly large, node %d\n", nfree(b), noden);
                   1216: -              errcnt++;
                   1217: -      }
                   1218: -      if(b->kcnt < 0) {
                   1219: -              printf("kcnt %d < 0, node %d\n", b->kcnt, noden);
                   1220: -              return(-1);
                   1221: -      }
                   1222: -      p = (char *)(b+1);
                   1223: -      for(i = 0; i < b->kcnt; i++) {
                   1224: -              d = (dkey *)p;
                   1225: -              if(d->dlen < DKEYSZ) {
                   1226: -                      printf("node %d, key %d, dlen %d too small\n", noden, i, d->dlen);
                   1227: -                      return(-1);
                   1228: -              }
                   1229: -              if(b->hlev)
                   1230: -                      sz += sizeof(ndaddr);
                   1231: -              else if(!(b->htype & INDEX))
                   1232: -                      sz += sizeof(lfaddr);
                   1233: -              if((sz += d->dlen) > NDSZ) {
                   1234: -                      printf("node %d, contents too large\n", noden);
                   1235: -                      return(-1);
                   1236: -              }
                   1237: -              p += d->dlen;
                   1238: -      }
                   1239: -      if(b->hlev)
                   1240: -              sz += sizeof(ndaddr);
                   1241: -      if(sz != NDSZ) {
                   1242: -              printf("node %d, size %d ndsz %d\n", noden, sz, NDSZ);
                   1243: -              return(-1);
                   1244: -      }
                   1245: -      /* check key ordering */
                   1246: -      p = (char *)(b + 1);
                   1247: -      d = (dkey *)p;
                   1248: -      if(d->dcom != 0) {
                   1249: -              printf("node %d first key has dcom %d > 0\n", noden, d->dcom);
                   1250: -              return(-1);
                   1251: -      }
                   1252: -      plen = lokey.mlen;
                   1253: -      for(i = 0; i < plen; i++)
                   1254: -              prefix[i] = lokey.mdata[i];
                   1255: -      for(i = 0; i < b->kcnt; i++) {
                   1256: -              if(d->dcom > plen) {
                   1257: -                      printf("node %d key %d, dcom %d bigger than len %d of prev key\n",
                   1258: -                              noden, i, d->dcom, plen);
                   1259: -                      return(-1);
                   1260: -              }
                   1261: -              for(j = 0; j < d->dlen - DKEYSZ; j++) {
                   1262: -                      if(j + d->dcom > plen)
                   1263: -                              break;
                   1264: -                      if(d->dkey[j] < prefix[d->dcom + j]) {
                   1265: -                              printf("node %d, key %d out of order\n",
                   1266: -                                      noden, i);
                   1267: -                              errcnt++;
                   1268: -                              break;
                   1269: -                      }
                   1270: -                      else if(d->dkey[j] == prefix[d->dcom + j])
                   1271: -                              continue;
                   1272: -                      else
                   1273: -                              break;
                   1274: -              }
                   1275: -              for(j = 0; j < d->dlen - DKEYSZ; j++)
                   1276: -                      prefix[j + d->dcom] = d->dkey[j];
                   1277: -              plen = j + d->dcom;
                   1278: -      }
                   1279: -      for(i = 0; i < plen && i < hikey.mlen; i++) {
                   1280: -              if(prefix[i] < hikey.mdata[i])
                   1281: -                      return(0);
                   1282: -              else if(prefix[i] == hikey.mdata[i])
                   1283: -                      continue;
                   1284: -              printf("node %d last key too large pref %s, hi %s\n", noden, prefix, hikey.mdata);
                   1285: -              return(-1);
                   1286: -      }
                   1287: -      if(plen > hikey.mlen) {
                   1288: -              printf("node %d last key too large plen %d, hikey.len %d\n", noden, plen, hikey.mlen);
                   1289: -              return(-1);
                   1290: -      }
                   1291: -      return(0);
                   1292: -}
                   1293: -
                   1294: -error(s)
                   1295: -char *s;
                   1296: -{
                   1297: -      printf("%s\n", s);
                   1298: -      exit(1);
                   1299: -}
                   1300: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:btdiag.c\n"};
                   1301: -/*1100001011001101*/
                   1302: //GO.SYSIN DD btdiag.c
                   1303: echo btexer.c 1>&2
                   1304: sed 's/.//' >btexer.c <<'//GO.SYSIN DD btexer.c'
                   1305: -#include "cbt.h"
                   1306: -extern char *malloc();
                   1307: -
                   1308: -bfile *bt;
                   1309: -mbuf *key;
                   1310: -char *state;
                   1311: -#define IN    1
                   1312: -#define OUT   2
                   1313: -int cnt, keysz;
                   1314: -char *buf;
                   1315: -char cmdbuf[128];
                   1316: -mbuf rec = {"", 0};
                   1317: -extern char *outkey();
                   1318: -char *filename;
                   1319: -
                   1320: -main(argc, argv)
                   1321: -char **argv;
                   1322: -{     int i;
                   1323: -      if(argc != 3)
                   1324: -              error("usage: file key-cnt");
                   1325: -      bt = bopen(filename = argv[1], 2);
                   1326: -      if(bt == 0)
                   1327: -              error("bopen");
                   1328: -      sprintf(cmdbuf, "btdiag %s", argv[1]);
                   1329: -      cnt = atoi(argv[2]);
                   1330: -      printf("cnt = %d\n", cnt);
                   1331: -      key = (mbuf *)malloc(cnt * sizeof(mbuf));
                   1332: -      keysz = NDSZ/5;
                   1333: -      if(keysz > MAXKLEN)
                   1334: -              keysz = MAXKLEN;
                   1335: -      printf("keysz %d\n", keysz);
                   1336: -      buf = malloc((keysz + 1) * cnt);
                   1337: -      state = malloc(cnt);
                   1338: -      if(buf == 0 || state == 0)
                   1339: -              error("key malloc");
                   1340: -      for(i = 0; i < cnt; i++)
                   1341: -              state[i] = OUT;
                   1342: -      for(i = 0; i < cnt; i++)
                   1343: -              key[i].mlen = keysz;
                   1344: -      for(i = 0; i < cnt; i++)
                   1345: -              key[i].mdata = buf + i * (keysz + 1);
                   1346: -      srand(0);
                   1347: -      for(i = 0; i < cnt * (keysz + 1); i++)
                   1348: -              buf[i] = rand() % 94 + ' ' + 1;
                   1349: -      for(i = 0; i < cnt; i++)
                   1350: -              buf[i * (keysz + 1) + keysz] = 0;
                   1351: -      doit();
                   1352: -      printf("sbrk %d\n", sbrk(0));
                   1353: -      exit(0);
                   1354: -}
                   1355: -
                   1356: -doit()
                   1357: -{
                   1358: -      allin();
                   1359: -      test("allin ok\n");
                   1360: -      checkseek();
                   1361: -      out(500);
                   1362: -      test("out 500 ok\n");
                   1363: -      checkseek();
                   1364: -      in(500);
                   1365: -      test("in 500 ok\n");
                   1366: -      checkseek();
                   1367: -      out(700);
                   1368: -      test("out 700 ok\n");
                   1369: -      checkseek();
                   1370: -      in(700);
                   1371: -      test("in 700 ok\n");
                   1372: -      checkseek();
                   1373: -      out(1000);
                   1374: -      test("out 1000 ok\n");
                   1375: -      checkseek();
                   1376: -      in(100);
                   1377: -      test("in 100 ok\n");
                   1378: -      checkseek();
                   1379: -      in(200);
                   1380: -      test("in 200 ok\n");
                   1381: -      checkseek();
                   1382: -      in(300);
                   1383: -      test("in 300 ok\n");
                   1384: -      checkseek();
                   1385: -}
                   1386: -
                   1387: -test(s)
                   1388: -char *s;
                   1389: -{     int n;
                   1390: -      bclose(bt);
                   1391: -      n = system(cmdbuf);
                   1392: -      if(n) {
                   1393: -              printf("%s returned %d\n", cmdbuf, n);
                   1394: -              exit(1);
                   1395: -      }
                   1396: -      else
                   1397: -              printf(s);
                   1398: -      bt = bopen(filename, 2);
                   1399: -      if(bt == NULL)
                   1400: -              error(filename);
                   1401: -}
                   1402: -
                   1403: -error(s)
                   1404: -char *s;
                   1405: -{
                   1406: -      perror(s);
                   1407: -      exit(1);
                   1408: -}
                   1409: -
                   1410: -allin()
                   1411: -{     int i;
                   1412: -      for(i = 0; i < cnt; i++) {
                   1413: -              if(state[i] == IN)
                   1414: -                      continue;
                   1415: -              if(bwrite(bt, key[i], rec) == EOF)
                   1416: -                      printf("write error %d on key %d\n", errno, i);
                   1417: -              else
                   1418: -                      state[i] = IN;
                   1419: -      }
                   1420: -}
                   1421: -
                   1422: -in(n)
                   1423: -{     int i;
                   1424: -      for(i = 0; i < cnt; i++) {
                   1425: -              if(state[i] == IN || (rand() % 1007) >= n)
                   1426: -                      continue;
                   1427: -              else if(bwrite(bt, key[i], rec) == EOF)
                   1428: -                      printf("write error %d on key %d\n", errno, i);
                   1429: -              else
                   1430: -                      state[i] = IN;
                   1431: -      }
                   1432: -}
                   1433: -
                   1434: -out(n)
                   1435: -{     int i, count = 0;
                   1436: -      for(i = 0; i < cnt; i++) {
                   1437: -              if(state[i] == OUT || (rand() % 1007) >= n)
                   1438: -                      continue;
                   1439: -              if(bdelete(bt, key[i], rec) != 1) {
                   1440: -                      printf("bdelete error %d on key %s\n", errno, outkey(i));
                   1441: -                      printf("out(%d) deleted %d\n", n, count);
                   1442: -                      bflush(bt);
                   1443: -                      exit(1);
                   1444: -              }
                   1445: -              else if(bt->fatal)
                   1446: -                      printf("set fatal flag, bdelete key %d %s err %d\n", i, outkey(i), errno);
                   1447: -              else {
                   1448: -                      count++;
                   1449: -                      state[i] = OUT;
                   1450: -              }
                   1451: -      }
                   1452: -}
                   1453: -
                   1454: -checkseek()
                   1455: -{     int i, j, count = 0;
                   1456: -      mbuf x;
                   1457: -      printf("\tcheckseek");
                   1458: -      for(i = 0; i < cnt; i++) {
                   1459: -              if(state[i] == OUT)
                   1460: -                      continue;
                   1461: -              if(bseek(bt, key[i]) != FOUND) {
                   1462: -                      printf("sought key %s, not found\n", key[i].mdata);
                   1463: -                      continue;
                   1464: -              }
                   1465: -              x = bkey(bt);
                   1466: -              for(j = 0; j < keysz; j++)
                   1467: -                      if(key[i].mdata[j] != x.mdata[j]) {
                   1468: -                              printf("bkey mismatch at key %d\n", i);
                   1469: -                              break;
                   1470: -                      }
                   1471: -              count++;
                   1472: -      }
                   1473: -      printf(" saw %d\n", count);
                   1474: -}
                   1475: -
                   1476: -char *
                   1477: -outkey(n)
                   1478: -{     static char kb[MAXKLEN + 1];
                   1479: -      int i;
                   1480: -      strncpy(kb, key[n].mdata, keysz);
                   1481: -      return(kb);
                   1482: -}
                   1483: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:btexer.c\n"};
                   1484: -/*1101101100011000*/
                   1485: //GO.SYSIN DD btexer.c
                   1486: echo btran.c 1>&2
                   1487: sed 's/.//' >btran.c <<'//GO.SYSIN DD btran.c'
                   1488: -#include "stdio.h"
                   1489: -#define MAX   8192
                   1490: -char tab = '\t';
                   1491: -char *line, *oline;
                   1492: -char abuf[MAX], bbuf[MAX];
                   1493: -int cnt, ocnt;
                   1494: -main()
                   1495: -{     long lcnt = 0;
                   1496: -      line = abuf;
                   1497: -      oline = bbuf;
                   1498: -      for(; !feof(stdin); ) {
                   1499: -              lcnt++;
                   1500: -              (void) fgets(line, MAX, stdin);
                   1501: -              if(feof(stdin)) cnt = 0;
                   1502: -              else cnt = strlen(line);
                   1503: -              if(cnt >= MAX-1) {
                   1504: -                      fprintf(stderr, "line %ld too long\n", lcnt);
                   1505: -                      cnt = 0;
                   1506: -              }
                   1507: -              output();
                   1508: -      }
                   1509: -      exit(0);
                   1510: -}
                   1511: -output()
                   1512: -{     unsigned short u;
                   1513: -      char *p;
                   1514: -      if(ocnt <= 1) { /* oline was used to give ooline a newline */
                   1515: -              swtch();
                   1516: -              return;
                   1517: -      }
                   1518: -      if(cnt != 1)    /* line isnt a newline to be added to oline */
                   1519: -              oline[--ocnt] = 0;
                   1520: -      else oline[ocnt] = 0;
                   1521: -      for(p = oline; *p && *p != tab; p++);
                   1522: -      u = p - oline;
                   1523: -      (void) fwrite((char *)&u, 1, sizeof(u), stdout);
                   1524: -      (void) fwrite(oline, (int)u, 1, stdout);
                   1525: -      if(*p == tab)
                   1526: -              p++;
                   1527: -      if(oline + ocnt - p < 0)
                   1528: -              u = 0;
                   1529: -      else u = oline + ocnt - p;
                   1530: -      (void) fwrite((char *)&u, 1, sizeof(u), stdout);
                   1531: -      (void) fwrite(p, (int)u, 1, stdout);
                   1532: -      swtch();
                   1533: -}
                   1534: -swtch()
                   1535: -{     char *x;
                   1536: -      x = line;
                   1537: -      line = oline;
                   1538: -      oline = x;
                   1539: -      ocnt = cnt;
                   1540: -}
                   1541: -static char VER[] = "\n80/2/13:btran.c\n";
                   1542: -/*1111100011110011*/
                   1543: //GO.SYSIN DD btran.c
                   1544: echo btreport.c 1>&2
                   1545: sed 's/.//' >btreport.c <<'//GO.SYSIN DD btreport.c'
                   1546: -#include "stdio.h"
                   1547: -#include "cbt.h"
                   1548: -#include "sys/types.h"
                   1549: -#include "sys/stat.h"
                   1550: -extern bfile *bopen();
                   1551: -
                   1552: -long ndcnt[MXHT + 1];
                   1553: -long frcnt, reccnt, reclen;
                   1554: -bfile *bt;
                   1555: -
                   1556: -main(argc, argv)
                   1557: -char **argv;
                   1558: -{     int i, j;
                   1559: -      for(i = 1; i < argc; i++) {
                   1560: -              doarg(argv[i]);
                   1561: -              for(j = 0; j <= MXHT; j++)
                   1562: -                      ndcnt[j] = 0;
                   1563: -              frcnt = reccnt = reclen = 0;
                   1564: -              if(i+1 < argc)
                   1565: -                      putchar('\n');
                   1566: -      }
                   1567: -      exit(0);
                   1568: -}
                   1569: -
                   1570: -doarg(s)
                   1571: -char *s;
                   1572: -{     struct stat statbuf;
                   1573: -      long x;
                   1574: -      int i;
                   1575: -      bt = bopen(s, 0);
                   1576: -      if(bt == NULL) {
                   1577: -              i = strlen(s);
                   1578: -              if(s[i-2] == '.') {
                   1579: -                      s[i-2] = 0;
                   1580: -                      if(s[i-1] == 'F')
                   1581: -                              return;
                   1582: -                      if(s[i-1] == 'T')
                   1583: -                              bt = bopen(s, 0);
                   1584: -              }
                   1585: -              if(bt == NULL) {
                   1586: -                      perror(s);
                   1587: -                      return;
                   1588: -              }
                   1589: -      }
                   1590: -      fstat(bt->tfd, &statbuf);
                   1591: -      printf("%s.T %ld bytes", s, statbuf.st_size);
                   1592: -      if(bt->dfd > 0 && fstat(bt->dfd, &statbuf) == 0)
                   1593: -              printf(", %s.F %ld bytes", s, statbuf.st_size);
                   1594: -      putchar('\n');
                   1595: -      donode((ndaddr)0);
                   1596: -      for(x = i = 0; i <= MXHT; i++)
                   1597: -              x += ndcnt[i] * NDSZ;
                   1598: -      printf("%ld bytes used in tree\n", x);
                   1599: -      for(i = 0; i <= bt->height; i++)
                   1600: -              printf(" %ld nodes at level %d", ndcnt[i], i);
                   1601: -      printf("\n%ld bytes free\n", frcnt);
                   1602: -      printf("%ld records totalling %ld bytes\n", reccnt, reclen);
                   1603: -      bclose(bt);
                   1604: -}
                   1605: -
                   1606: -/* this routine believes the tree is well-formed */
                   1607: -donode(n)
                   1608: -ndaddr n;
                   1609: -{     char buf[NDSZ];
                   1610: -      hdr *b = (hdr *)buf;
                   1611: -      int i;
                   1612: -      (void) lseek(bt->tfd, (long)NDSZ * n, 0);
                   1613: -      i = read(bt->tfd, buf, NDSZ);
                   1614: -      if(i != NDSZ) {
                   1615: -              printf("btreport: attempt to read node %d failed\n", n);
                   1616: -              perror("breport");
                   1617: -              exit(1);
                   1618: -      }
                   1619: -      ndcnt[b->hlev]++;
                   1620: -      frcnt += nfree(b);
                   1621: -      if(b->hlev)
                   1622: -              for(i = 0; i <= b->kcnt; i++)
                   1623: -                      donode(*ndadr(b, i));
                   1624: -      else
                   1625: -              for(i = 0; i < b->kcnt; i++) {
                   1626: -                      reccnt++;
                   1627: -                      if(!(b->htype & INDEX))
                   1628: -                              reclen += lfadr(b, i)->llen;
                   1629: -              }
                   1630: -}
                   1631: -static struct D { struct D *a; char *b;} VER = {&VER,"\n86/8/12:btreport.c\n"};
                   1632: //GO.SYSIN DD btreport.c
                   1633: echo btsquash.c 1>&2
                   1634: sed 's/.//' >btsquash.c <<'//GO.SYSIN DD btsquash.c'
                   1635: -#include "stdio.h"
                   1636: -#include "cbt.h"
                   1637: -
                   1638: -extern int errno;
                   1639: -mbuf key, value;
                   1640: -char kbuf[NDSZ], vbuf[32767];
                   1641: -bfile *bfd;
                   1642: -FILE *pfd;
                   1643: -extern FILE *popen();
                   1644: -char iflag, rflag;
                   1645: -
                   1646: -main(argc, argv)
                   1647: -char **argv;
                   1648: -{
                   1649: -      if(argc != 2) {
                   1650: -              fprintf(stderr, "usage; %s file-name\n", argv[0]);
                   1651: -              exit(1);
                   1652: -      }
                   1653: -      bfd = bopen(argv[1], 0);
                   1654: -      if(bfd == NULL)
                   1655: -              fail(argv[1]);
                   1656: -      strcpy(vbuf, "cbt creat ");
                   1657: -      if(bfd->path[0]->htype & INDEX) {
                   1658: -              iflag = 1;
                   1659: -              strcat(vbuf, "-i ");
                   1660: -      }
                   1661: -      if(bfd->path[0]->htype & READONLY) {
                   1662: -              rflag = 1;
                   1663: -              strcat(vbuf, "-r");
                   1664: -      }
                   1665: -      sprintf(kbuf, "%s TS%d", vbuf, getpid());
                   1666: -      if(system(kbuf) != 0) {
                   1667: -              fprintf(stderr, "%s failed\n", kbuf);
                   1668: -              exit(1);
                   1669: -      }
                   1670: -      /* this refers to the installed version? */
                   1671: -      sprintf(kbuf, "cbt build -r TS%d", getpid());
                   1672: -      pfd = popen(kbuf, "w");
                   1673: -      if(pfd == NULL)
                   1674: -              fail(kbuf);
                   1675: -      key.mdata = kbuf;
                   1676: -      value.mdata = vbuf;
                   1677: -      errno = 0;
                   1678: -      while(bread(bfd, &key, &value) != EOF) {
                   1679: -              (void) fwrite((char *)&key.mlen, 1, sizeof(key.mlen), pfd);
                   1680: -              (void) fwrite(key.mdata, 1, key.mlen, pfd);
                   1681: -              (void) fwrite((char *)&value.mlen, 1, sizeof(value.mlen), pfd);
                   1682: -              (void) fwrite(value.mdata, 1, value.mlen, pfd);
                   1683: -              if(ferror(pfd))
                   1684: -                      fail("write to build");
                   1685: -      }
                   1686: -      if(errno)
                   1687: -              fail("extracting");
                   1688: -      if(pclose(pfd) != 0)
                   1689: -              fail("pipe close");
                   1690: -      sprintf(kbuf, "%s.T", argv[1]);
                   1691: -      sprintf(vbuf, "TS%d.T", getpid());
                   1692: -      unlink(kbuf);
                   1693: -      link(vbuf, kbuf);
                   1694: -      if(iflag)
                   1695: -              exit(0);
                   1696: -      sprintf(kbuf, "%s.F", argv[1]);
                   1697: -      sprintf(vbuf, "TS%d.F", getpid());
                   1698: -      unlink(kbuf);
                   1699: -      link(vbuf, kbuf);
                   1700: -      if(errno)
                   1701: -              perror("linking");
                   1702: -      exit(0);
                   1703: -}
                   1704: -
                   1705: -fail(s)
                   1706: -char *s;
                   1707: -{
                   1708: -      perror(s);
                   1709: -      exit(2);
                   1710: -}
                   1711: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/4/26:btsquash.c\n"};
                   1712: -/*0100011001101001*/
                   1713: //GO.SYSIN DD btsquash.c
                   1714: echo bttest.c 1>&2
                   1715: sed 's/.//' >bttest.c <<'//GO.SYSIN DD bttest.c'
                   1716: -#include "stdio.h"
                   1717: -#include "cbt.h"
                   1718: -extern char *malloc();
                   1719: -extern bfile *bopen();
                   1720: -extern mbuf bkey();
                   1721: -extern long lseek();
                   1722: -
                   1723: -char *onearg();
                   1724: -mbuf key, value;
                   1725: -bfile *it;
                   1726: -#define OPEN  1
                   1727: -#define CLOSE 2
                   1728: -#define SEEK  3
                   1729: -#define FIRST 4
                   1730: -#define NEXT  5
                   1731: -#define WRITE 6
                   1732: -#define BT    7
                   1733: -#define LEV   8
                   1734: -#define NODE  9
                   1735: -#define KEY   10
                   1736: -#define FLUSH 11
                   1737: -#define COMMIT        12
                   1738: -#define SHELL 13
                   1739: -#define DELETE        14
                   1740: -#define START 15
                   1741: -#define CHECK 16
                   1742: -struct cmd
                   1743: -{     int cmt, cln;
                   1744: -      char *ccm;
                   1745: -} cmnd[] =
                   1746: -{     {OPEN, 4, "open"},
                   1747: -      {CLOSE, 5, "close"},
                   1748: -      {SHELL, 1, "!"},
                   1749: -      {DELETE, 6, "delete"},
                   1750: -      {SEEK, 4, "seek"},
                   1751: -      {FIRST, 5, "first"},
                   1752: -      {NEXT, 4, "next"},
                   1753: -      {NEXT, 4, "read"},
                   1754: -      {WRITE, 5, "write"},
                   1755: -      {CHECK, 5, "check"},
                   1756: -      {BT, 2, "bt"},
                   1757: -      {LEV, 3, "lev"},
                   1758: -      {NODE, 4, "node"},
                   1759: -      {KEY, 3, "key"},
                   1760: -      {FLUSH, 5, "flush"},
                   1761: -      {COMMIT, 6, "commit"},
                   1762: -      {START, 5, "start"},
                   1763: -      {START, 7, "trstart"},
                   1764: -      {0, 0, 0}
                   1765: -};
                   1766: -char line[128];
                   1767: -char ndbuf[512];
                   1768: -main()
                   1769: -{
                   1770: -      int n;
                   1771: -      char *s, *p;
                   1772: -      key.mdata = malloc(200);
                   1773: -      value.mdata = malloc(200);
                   1774: -      for(;;) {
                   1775: -              for(n = 0; n < sizeof(line); n++)
                   1776: -                      line[n] = 0;
                   1777: -              (void) fgets(line, sizeof(line), stdin);
                   1778: -              if(feof(stdin)) break;
                   1779: -              switch(cmtp(line)) {
                   1780: -              default:
                   1781: -                      printf("?\n");
                   1782: -                      break;
                   1783: -              case CLOSE:
                   1784: -                      bclose(it);
                   1785: -                      break;
                   1786: -              case SHELL:
                   1787: -                      (void) system(line);
                   1788: -                      printf("!\n");
                   1789: -                      break;
                   1790: -              case START:
                   1791: -      /*              printf("%d\n", trstart()); */
                   1792: -                      break;
                   1793: -              case COMMIT:
                   1794: -      /*              btcommit(); */
                   1795: -                      break;
                   1796: -              case FLUSH:
                   1797: -                      bflush(it);
                   1798: -                      break;
                   1799: -              case OPEN:
                   1800: -                      s = onearg(line);
                   1801: -                      it = bopen(s, 2);
                   1802: -                      if(it == NULL || errno)
                   1803: -                      {       perror(s);
                   1804: -                      }
                   1805: -                      break;
                   1806: -              case DELETE:
                   1807: -                      s = onearg(line);
                   1808: -                      if(s[strlen(s)-1] == '\n')
                   1809: -                              s[strlen(s)-1] = 0;
                   1810: -                      todatum(s, &key);
                   1811: -                      printf("%d\n", bdelete(it, key));
                   1812: -                      break;
                   1813: -              case SEEK:
                   1814: -                      s = onearg(line);
                   1815: -                      if(s[strlen(s)-1] == '\n')
                   1816: -                              s[strlen(s)-1] = 0;
                   1817: -                      todatum(s, &key);
                   1818: -                      printf("%d\n", bseek(it, key));
                   1819: -                      break;
                   1820: -              case FIRST:
                   1821: -                      printf("%d\n", bfirst(it));
                   1822: -                      break;
                   1823: -              case NEXT:
                   1824: -                      printf("%d - ", bread(it, &key, &value));
                   1825: -                      prbuf(value);
                   1826: -                      printf(" | ");
                   1827: -                      prbuf(key);
                   1828: -                      putchar('\n');
                   1829: -                      break;
                   1830: -              case WRITE:
                   1831: -                      twoarg(line, &s, &p);
                   1832: -                      todatum(s, &key);
                   1833: -                      todatum(p, &value);
                   1834: -                      printf("%d\n", bwrite(it, key, value));
                   1835: -                      break;
                   1836: -              case BT:
                   1837: -                      prbt(it);
                   1838: -                      break;
                   1839: -              case LEV:
                   1840: -                      (void) sscanf(line, "%d", &n);
                   1841: -                      if(n < 0 || n > it->height)
                   1842: -                      {       printf("out of range\n");
                   1843: -                              break;
                   1844: -                      }
                   1845: -                      tprnode(it->path[n]);
                   1846: -                      break;
                   1847: -              case NODE:
                   1848: -                      (void) sscanf(line, "%d", &n);
                   1849: -                      (void) lseek(it->tfd, (long)n*NDSZ, 0);
                   1850: -                      (void) read(it->tfd, ndbuf, NDSZ);
                   1851: -                      tprnode((hdr *)ndbuf);
                   1852: -                      break;
                   1853: -              case CHECK:
                   1854: -                      (void) sscanf(line, "%d", &n);
                   1855: -                      (void) lseek(it->tfd, (long)n * NDSZ, 0);
                   1856: -                      (void) read(it->tfd, ndbuf, NDSZ);
                   1857: -                      checknode((hdr *)ndbuf);
                   1858: -                      break;
                   1859: -              case KEY:
                   1860: -                      printf("%d ", breclen(it));
                   1861: -                      prbuf(bkey(it));
                   1862: -                      putchar('\n');
                   1863: -                      break;
                   1864: -              }
                   1865: -      }
                   1866: -      exit(0);
                   1867: -}
                   1868: -cmtp(s) char *s;
                   1869: -{     struct cmd *p;
                   1870: -      int i;
                   1871: -      for(p=cmnd; p->cln != 0; p++)
                   1872: -              if(strncmp(s, p->ccm, p->cln) == 0)
                   1873: -              {       for(i=0; i<p->cln; i++)
                   1874: -                              line[i] =' ';
                   1875: -                      return(p->cmt);
                   1876: -              }
                   1877: -      return(-1);
                   1878: -}
                   1879: -char *onearg(s) char *s;
                   1880: -{     char *p, *q;
                   1881: -      for(p=s; *p == ' '; p++);
                   1882: -      for(q=p; *q && *q!='\n'; q++);
                   1883: -      *q = 0;
                   1884: -      return(p);
                   1885: -}
                   1886: -todatum(s, k) char *s; mbuf *k;
                   1887: -{     int i;
                   1888: -      k->mlen = strlen(s);
                   1889: -      if(s[k->mlen - 1] == '\n')
                   1890: -              k->mlen--;
                   1891: -      for(i=0; i<k->mlen; i++)
                   1892: -              k->mdata[i] = s[i];
                   1893: -}
                   1894: -twoarg(a, b, c) char *a, **b, **c;
                   1895: -{     char *p, *q;
                   1896: -      for(; *a==' '; a++);
                   1897: -      for(p=a; *p && *p!='\t'; p++);
                   1898: -      *p++ = 0;
                   1899: -      for(q=p; *q && *q!='\n'; q++);
                   1900: -      *q = 0;
                   1901: -      *b = a;
                   1902: -      *c = p;
                   1903: -}
                   1904: -prbuf(a) mbuf a;
                   1905: -{     int i;
                   1906: -      printf("%d:", a.mlen);
                   1907: -      for(i=0; i<a.mlen; i++)
                   1908: -              putchar(a.mdata[i]);
                   1909: -}
                   1910: -prbt(a) bfile *a;
                   1911: -{     int i;
                   1912: -      printf("ht %d adv %d rdw %d flags ", a->height, a->advnc,
                   1913: -              a->rdwrt);
                   1914: -      for(i = 0; i <= MXHT; i++)
                   1915: -              printf(" %d", a->flag[i]);
                   1916: -      putchar('\n');
                   1917: -      printf("nodes ");
                   1918: -      for(i = 0; i <= MXHT; i++)
                   1919: -              printf(" %d", a->loc[i]);
                   1920: -      putchar('\n');
                   1921: -      printf("rdkey #%d:", a->rdptr.rnum);
                   1922: -      printf(":\n");
                   1923: -}
                   1924: -tprnode(a) hdr *a;
                   1925: -{     int i;
                   1926: -      dkey *q;
                   1927: -      prhdr(a);
                   1928: -      q = (dkey *)(a+1);
                   1929: -      for(i = 0; i < a->kcnt; i++) {
                   1930: -              if(a->hlev == 0)
                   1931: -                      prlfa(lfadr(a, i));
                   1932: -              else prnda(ndadr(a, i));
                   1933: -              prkey(q);
                   1934: -              q = (dkey *)((char *)q + q->dlen);
                   1935: -      }
                   1936: -      if(a->hlev)
                   1937: -              prnda(ndadr(a, i));
                   1938: -      putchar('\n');
                   1939: -}
                   1940: -checknode(a)
                   1941: -hdr *a;
                   1942: -{     int i;
                   1943: -      char *p;
                   1944: -      for(i = 0, p = (char *)(a + 1); i < a->kcnt; i++)
                   1945: -              p += *p;
                   1946: -      i = p - (char *)a + nfree(a) + sizeof(trailer);
                   1947: -      if(a->hlev)
                   1948: -              i += (a->kcnt + 1) * sizeof(ndaddr);
                   1949: -      else if(!treeonly(it))
                   1950: -              i += a->kcnt * sizeof(lfaddr);
                   1951: -      if(i == NDSZ) {
                   1952: -              printf("ok\n");
                   1953: -              return;
                   1954: -      }
                   1955: -      printf("nfree should be %d not %d\n", NDSZ - i + nfree(a),
                   1956: -              nfree(a));
                   1957: -}
                   1958: -prhdr(a) hdr *a;
                   1959: -{
                   1960: -      printf("stamp %ld kcnt %d type %d lev %d free %d\n",
                   1961: -              a->hstamp, a->kcnt, a->htype, a->hlev, nfree(a));
                   1962: -}
                   1963: -prlfa(a) lfaddr *a;
                   1964: -{
                   1965: -      if(treeonly(it))
                   1966: -              printf("\t");
                   1967: -      else
                   1968: -              printf("%ld %u\t", a->lloc, a->llen);
                   1969: -}
                   1970: -prnda(a) ndaddr *a;
                   1971: -{
                   1972: -      printf("%u\t", *a);
                   1973: -}
                   1974: -prkey(b) dkey *b;
                   1975: -{     int i;
                   1976: -      for(i = 0; i < b->dcom; i++)
                   1977: -              putchar(' ');
                   1978: -      for(i = 0; i < b->dlen - DKEYSZ; i++)
                   1979: -              putchar(b->dkey[i]);
                   1980: -      putchar('\n');
                   1981: -}
                   1982: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bttest.c\n"};
                   1983: -/*0111000111010001*/
                   1984: //GO.SYSIN DD bttest.c
                   1985: echo bwrite.c 1>&2
                   1986: sed 's/.//' >bwrite.c <<'//GO.SYSIN DD bwrite.c'
                   1987: -#include "cbt.h"
                   1988: -#include "pr.h"
                   1989: -
                   1990: -typedef union {
                   1991: -      ndaddr na;
                   1992: -      lfaddr la;
                   1993: -} addr;
                   1994: -static char splitting[MXHT+1];
                   1995: -extern bfile *curbf;
                   1996: -extern ndaddr oldnode(), newnode();
                   1997: -extern char *malloc();
                   1998: -
                   1999: -extern long brecwrite();
                   2000: -
                   2001: -bwrite(bf, key, rec) mbuf key, rec; bfile *bf;
                   2002: -{     addr u;
                   2003: -      int n;
                   2004: -      if(bf == NULL)
                   2005: -              return(EOF);
                   2006: -      if(!bf->rdwrt) {
                   2007: -              errno = BNOWRITE;
                   2008: -              return(EOF);
                   2009: -      }
                   2010: -      if(notran(bf))
                   2011: -              return(EOF);
                   2012: -      if(key.mlen > MAXKLEN)
                   2013: -              return(EOF);
                   2014: -      if(!treeonly(bf)) {
                   2015: -              u.la.llen = rec.mlen;
                   2016: -              u.la.lloc = brecwrite(rec);
                   2017: -              if(u.la.lloc == EOF)
                   2018: -                      return(EOF);
                   2019: -      }
                   2020: -      if(desce(bf, key, (private *)NULL) == EOF)
                   2021: -              return(EOF);
                   2022: -      n = xinsert(0, key, u);
                   2023: -      (void) bseek(bf, key);
                   2024: -      return(n);
                   2025: -}
                   2026: -
                   2027: -fixpath(bf)
                   2028: -bfile *bf;
                   2029: -{     addr u;
                   2030: -      hdr *b;
                   2031: -      int i, n, j;
                   2032: -      for(i = 0; i < bf->height; i++) {
                   2033: -              if(!mustwrite(bf, i))
                   2034: -                      continue;
                   2035: -              n = bf->loc[i];
                   2036: -              if((u.na = oldnode(i)) == EOF)
                   2037: -                      return(EOF);
                   2038: -              b = bf->path[i+1];
                   2039: -              for(j = 0; j <= b->kcnt; j++)
                   2040: -                      if(*ndadr(b, j) == n)
                   2041: -                              break;
                   2042: -              if(j > b->kcnt){ /* curtains, the parent doesn't point to us */
                   2043: -                      errno = BFATAL;
                   2044: -                      return(EOF);
                   2045: -              }
                   2046: -              *ndadr(b, j) = u.na;
                   2047: -              mustwrite(bf, i + 1) = 1;
                   2048: -      }
                   2049: -      return(0);
                   2050: -}
                   2051: -
                   2052: -xinsert(lev, key, u) mbuf key; addr u;
                   2053: -{     private x;
                   2054: -      int n, dellen;
                   2055: -      hdr *b = curbf->path[lev];
                   2056: -      char ba[NDSZ], bb[NDSZ];
                   2057: -      dkey *dx, *dy;
                   2058: -      if(splitting[lev])
                   2059: -              if(desce(curbf, key, (private *)NULL) == EOF)
                   2060: -                      return(EOF);
                   2061: -      n = xscan(b, key, &x);
                   2062: -      if(x.match == FOUND) {
                   2063: -              if(treeonly(curbf))
                   2064: -                      return(FOUND);
                   2065: -              else if(lev)
                   2066: -                      *ndadr(b, n) = u.na;
                   2067: -              else
                   2068: -                      *lfadr(b, n) = u.la;
                   2069: -              mustwrite(curbf, lev) = 1;
                   2070: -              return(FOUND);
                   2071: -      }
                   2072: -      dx = (dkey *)ba;
                   2073: -      dy = (dkey *)bb;
                   2074: -      dellen = newx(&x, key, dx, dy);
                   2075: -      if(lev)
                   2076: -              dellen += sizeof(ndaddr);
                   2077: -      else if(!treeonly(curbf))
                   2078: -              dellen += sizeof(lfaddr);
                   2079: -      if(dellen > nfree(b)) {
                   2080: -              if(nsplit(lev) == EOF)
                   2081: -                      return(EOF);
                   2082: -              splitting[lev] = 1;
                   2083: -              n = xinsert(lev, key, u);
                   2084: -              splitting[lev] = 0;
                   2085: -              return(n);
                   2086: -      }
                   2087: -      b = curbf->path[lev];   /* with thanks to brian meekings */
                   2088: -      addaddr(b, n, u);
                   2089: -      newkeys(b, &x, dx, dy);
                   2090: -      b->kcnt++;
                   2091: -      nfree(b) -= dellen;
                   2092: -      mustwrite(curbf, lev) = 1;
                   2093: -      return(NOTFOUND);
                   2094: -}
                   2095: -
                   2096: -newx(x, key, c, d) private *x; mbuf key; dkey *c, *d;
                   2097: -{     int i, j;
                   2098: -      if(x->match != EOF)
                   2099: -              c->dcom = x->ocom;
                   2100: -      else    c->dcom = x->ncom;
                   2101: -      i = key.mlen - c->dcom;
                   2102: -      c->dlen = DKEYSZ + i;
                   2103: -      mvgbt(c->dkey, key.mdata + c->dcom, i);
                   2104: -      if(x->match == EOF)
                   2105: -              return(c->dlen);
                   2106: -      j = x->ncom - x->d->dcom;
                   2107: -      d->dcom = x->ncom;
                   2108: -      d->dlen = x->d->dlen - j;
                   2109: -      mvgbt(d->dkey, x->d->dkey + j, d->dlen - DKEYSZ);
                   2110: -      return(c->dlen - j);
                   2111: -}
                   2112: -
                   2113: -addaddr(b, n, u)
                   2114: -hdr *b;
                   2115: -addr u;
                   2116: -{
                   2117: -      if(b->hlev) {
                   2118: -              mvgbt((char *)ndadr(b, b->kcnt + 1),
                   2119: -                      (char *)ndadr(b, b->kcnt),
                   2120: -                      sizeof(ndaddr) * (b->kcnt + 1 - n) );
                   2121: -              *ndadr(b, n) = u.na;
                   2122: -              return;
                   2123: -      }
                   2124: -      if(treeonly(curbf))
                   2125: -              return;
                   2126: -      mvgbt((char *)lfadr(b, b->kcnt), (char *)lfadr(b, b->kcnt - 1),
                   2127: -              sizeof(lfaddr) * (b->kcnt - n));
                   2128: -      *lfadr(b, n) = u.la;
                   2129: -}
                   2130: -
                   2131: -newkeys(b, x, c, d)
                   2132: -hdr *b;
                   2133: -private *x;
                   2134: -dkey *c, *d;
                   2135: -{     int n;
                   2136: -      char *ffree;
                   2137: -      if(b->hlev)
                   2138: -              ffree = (char *)ndadr(b, b->kcnt) - nfree(b);
                   2139: -      else if(treeonly(curbf))
                   2140: -              ffree = (char *)&nfree(b) - nfree(b);
                   2141: -      else
                   2142: -              ffree = (char *)lfadr(b, b->kcnt - 1) - nfree(b);
                   2143: -      if(x->match != EOF) {
                   2144: -              n = c->dlen + d->dlen;
                   2145: -              n -= x->d->dlen;
                   2146: -              mvgbt((char *)x->d + n, (char *)x->d, ffree - (char *)x->d);
                   2147: -              mvgbt((char *)x->d, (char *)c, c->dlen);
                   2148: -              mvgbt((char *)x->d + c->dlen, (char *)d, d->dlen);
                   2149: -      }
                   2150: -      else if(b->kcnt > 0)
                   2151: -              mvgbt((char *)x->d + x->d->dlen, (char *)c, c->dlen);
                   2152: -      else
                   2153: -              mvgbt((char *)x->d, (char *)c, c->dlen);
                   2154: -}
                   2155: -
                   2156: -nsplit(lev)
                   2157: -{     dkey *tod, *fromd;
                   2158: -      char prefix[MAXKLEN + 10];
                   2159: -      hdr *b = curbf->path[lev];
                   2160: -      mbuf key;
                   2161: -      addr u;
                   2162: -      union {
                   2163: -              lfaddr *la;
                   2164: -              ndaddr *na;
                   2165: -      } from, to;
                   2166: -      int mvd, x, i, count, n;
                   2167: -      hdr *ha;
                   2168: -      char a[NDSZ];
                   2169: -
                   2170: -      x = (NDSZ - sizeof(hdr) - sizeof(trailer)) / 2;
                   2171: -      ha = (hdr *) a;
                   2172: -      mvd = count = 0;
                   2173: -      tod = (dkey *)(ha + 1);
                   2174: -      fromd = (dkey *)(b + 1);
                   2175: -      if(lev == 0) {
                   2176: -              to.la = lfadr(ha, 0);
                   2177: -              from.la = lfadr(b, 0);
                   2178: -      }
                   2179: -      else {
                   2180: -              to.na = ndadr(ha, 0);
                   2181: -              from.na = ndadr(b, 0);
                   2182: -      }
                   2183: -      *ha = *b;
                   2184: -      n = (b->kcnt + 1)/2;
                   2185: -      if(lev && b->kcnt - n <= 1)
                   2186: -              n--;
                   2187: -      for(; count < n && mvd <= x; count++) {
                   2188: -              mvgbt((char *)tod, (char *)fromd, fromd->dlen);
                   2189: -              mvd += fromd->dlen;
                   2190: -              tod = (dkey *)((char *)tod + fromd->dlen);
                   2191: -              fromd = (dkey *)((char *)fromd + fromd->dlen);
                   2192: -              if(lev) {
                   2193: -                      *to.na-- = *from.na--;
                   2194: -                      mvd += sizeof(ndaddr);
                   2195: -              }
                   2196: -              else if(!treeonly(curbf)) {
                   2197: -                      *to.la-- = *from.la--;
                   2198: -                      mvd += sizeof(lfaddr);
                   2199: -              }
                   2200: -      }
                   2201: -      if(lev) {       /* another pointer for non-leaves */
                   2202: -              *to.na-- = *from.na--;
                   2203: -              mvd += sizeof(ndaddr);
                   2204: -      }
                   2205: -      ha->kcnt = count;
                   2206: -      nfree(ha) = NDSZ - sizeof(hdr) - sizeof(trailer) - mvd;
                   2207: -      /* if lev == 0, we promote the last key, else the next key */
                   2208: -      key.mlen = lastkey(ha, prefix);
                   2209: -      if(lev) {
                   2210: -              mvgbt(prefix + fromd->dcom, fromd->dkey, fromd->dlen - DKEYSZ);
                   2211: -              key.mlen = fromd->dcom + fromd->dlen - DKEYSZ;
                   2212: -              count++;
                   2213: -              fromd = (dkey *)((char *)fromd + fromd->dlen);
                   2214: -      }
                   2215: -      u.na = newnode(ha);
                   2216: -      if(u.na == EOF) {       /* error while splitting */
                   2217: -              curbf->fatal++;
                   2218: -              return(EOF);
                   2219: -      }
                   2220: -      key.mdata = prefix;
                   2221: -      /* other half */
                   2222: -      if(lev == 0)
                   2223: -              to.la = lfadr(ha, 0);
                   2224: -      else
                   2225: -              to.na = ndadr(ha, 0);
                   2226: -      tod = (dkey *)(ha + 1);
                   2227: -      tod->dcom = 0;
                   2228: -      tod->dlen = fromd->dlen + fromd->dcom;
                   2229: -      mvgbt(tod->dkey, prefix, fromd->dcom);
                   2230: -      mvgbt(tod->dkey + fromd->dcom, fromd->dkey, fromd->dlen - DKEYSZ);
                   2231: -      mvd = tod->dlen;
                   2232: -      fromd = (dkey *)((char *)fromd + fromd->dlen);
                   2233: -      tod = (dkey *)((char *)tod + tod->dlen);
                   2234: -      if(lev) {
                   2235: -              *to.na-- = *from.na--;
                   2236: -              mvd += sizeof(ndaddr);
                   2237: -      }
                   2238: -      else if(!treeonly(curbf)) {
                   2239: -              *to.la-- = *from.la--;
                   2240: -              mvd += sizeof(lfaddr);
                   2241: -      }
                   2242: -      count++;
                   2243: -      for(i = 1; count < b->kcnt; i++, count++) {
                   2244: -              mvgbt((char *)tod, (char *)fromd, fromd->dlen);
                   2245: -              mvd += fromd->dlen;
                   2246: -              tod = (dkey *)((char *)tod + tod->dlen);
                   2247: -              fromd = (dkey *)((char *)fromd + fromd->dlen);
                   2248: -              if(lev) {
                   2249: -                      *to.na-- = *from.na--;
                   2250: -                      mvd += sizeof(ndaddr);
                   2251: -              }
                   2252: -              else if(!treeonly(curbf)) {
                   2253: -                      *to.la-- = *from.la--;
                   2254: -                      mvd += sizeof(lfaddr);
                   2255: -              }
                   2256: -
                   2257: -      }
                   2258: -      if(lev) {
                   2259: -              *to.na-- = *from.na--;
                   2260: -              mvd += sizeof(ndaddr);
                   2261: -      }
                   2262: -      ha->kcnt = i;
                   2263: -      nfree(ha) = NDSZ - sizeof(hdr) - sizeof(trailer) - mvd;
                   2264: -      mvgbt((char *)b, (char *)ha, NDSZ);
                   2265: -      mustwrite(curbf, lev) = 1;
                   2266: -      if(lev < curbf->height) {
                   2267: -              if(xinsert(lev + 1, key, u) == EOF) {
                   2268: -                      curbf->fatal++;
                   2269: -                      return(EOF);
                   2270: -              }
                   2271: -      }
                   2272: -      else
                   2273: -              return(newroot(u, key, b));
                   2274: -      return(0);
                   2275: -}
                   2276: -
                   2277: -newroot(u, key, b)
                   2278: -addr u;
                   2279: -mbuf key;
                   2280: -hdr *b;
                   2281: -{     hdr *x;
                   2282: -      dkey *d;
                   2283: -      if(curbf->height >= MXHT) {
                   2284: -              errno = BTALL;
                   2285: -              curbf->fatal++;
                   2286: -              return(EOF);
                   2287: -      }
                   2288: -      if((x = curbf->path[b->hlev + 1] = (hdr *)malloc(NDSZ)) == NULL) {
                   2289: -              errno = BNOMEM;
                   2290: -              curbf->fatal++;
                   2291: -              return(EOF);
                   2292: -      }
                   2293: -      *x = *b;
                   2294: -      x->hlev++;
                   2295: -      d = (dkey *)(x + 1);
                   2296: -      d->dlen = DKEYSZ + key.mlen;
                   2297: -      d->dcom = 0;
                   2298: -      mvgbt(d->dkey, key.mdata, key.mlen);
                   2299: -      *ndadr(x, 0) = u.na;
                   2300: -      *ndadr(x, 1) = curbf->loc[b->hlev] = newnode(b);
                   2301: -      x->kcnt = 1;
                   2302: -      nfree(x) = NDSZ - sizeof(hdr) - sizeof(trailer) - DKEYSZ
                   2303: -              - key.mlen - 2 * sizeof(ndaddr);
                   2304: -      mustwrite(curbf, ++curbf->height) = 1;
                   2305: -      return(0);
                   2306: -}
                   2307: -
                   2308: -lastkey(b, s)
                   2309: -hdr *b;
                   2310: -char *s;
                   2311: -{     int i, n;
                   2312: -      dkey *p;
                   2313: -      p = (dkey *)(b + 1);
                   2314: -      for(n = i = 0; i < b->kcnt; i++) {
                   2315: -              mvgbt(s + p->dcom, p->dkey, p->dlen - DKEYSZ);
                   2316: -              n = p->dlen + p->dcom - DKEYSZ;
                   2317: -              p = (dkey *)((char *) p + p->dlen);
                   2318: -      }
                   2319: -      return(n);
                   2320: -}
                   2321: -
                   2322: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:bwrite.c\n"};
                   2323: -/*0010010000010101*/
                   2324: //GO.SYSIN DD bwrite.c
                   2325: echo diskrd.c 1>&2
                   2326: sed 's/.//' >diskrd.c <<'//GO.SYSIN DD diskrd.c'
                   2327: -#include "cbt.h"
                   2328: -
                   2329: -extern bfile *curbf;
                   2330: -extern long lseek();
                   2331: -
                   2332: -ndrd(lev, where) ndaddr where;
                   2333: -{
                   2334: -      register n;
                   2335: -      if(mustwrite(curbf, lev)) {
                   2336: -              /* do we ever get here? (yes, while splitting) */
                   2337: -              if(ndwrt(curbf->path[lev], curbf->loc[lev]) == EOF)
                   2338: -                      return(EOF);
                   2339: -              mustwrite(curbf, lev) = 0;
                   2340: -      }
                   2341: -      if(lseek(curbf->tfd, where * (long)NDSZ, 0) == -1)
                   2342: -              return(EOF);
                   2343: -      if((n = read(curbf->tfd, (char *)curbf->path[lev], NDSZ)) != NDSZ) {
                   2344: -              if(n >= 0)
                   2345: -                      errno = BRDERR;
                   2346: -              return(EOF);
                   2347: -      }
                   2348: -      curbf->loc[lev] = where;
                   2349: -      return(0);
                   2350: -}
                   2351: -
                   2352: -getincore(lev, where) ndaddr where;
                   2353: -{
                   2354: -      if(ndrd(lev, where) == EOF)
                   2355: -              return(EOF);
                   2356: -      if(curbf->path[lev]->hlev != lev) {
                   2357: -              errno = BRDERR;
                   2358: -              curbf->fatal++;
                   2359: -              return(EOF);
                   2360: -      }
                   2361: -      return(0);
                   2362: -}
                   2363: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:diskrd.c\n"};
                   2364: -/*1010100001000111*/
                   2365: //GO.SYSIN DD diskrd.c
                   2366: echo diskwrt.c 1>&2
                   2367: sed 's/.//' >diskwrt.c <<'//GO.SYSIN DD diskwrt.c'
                   2368: -#include "cbt.h"
                   2369: -
                   2370: -extern bfile *curbf;
                   2371: -extern long lseek();
                   2372: -
                   2373: -ndwrt(b, where) hdr *b; ndaddr where;
                   2374: -{
                   2375: -      register n;
                   2376: -      if(lseek(curbf->tfd, where * (long)NDSZ, 0) == -1)
                   2377: -              return(EOF);
                   2378: -      if((n = write(curbf->tfd, (char *)b, NDSZ)) != NDSZ) { /*unacceptable*/
                   2379: -              if(n >= 0)
                   2380: -                      errno = BIOWRT;
                   2381: -              curbf->fatal++;
                   2382: -              return(EOF);
                   2383: -      }
                   2384: -      return(0);
                   2385: -}
                   2386: -
                   2387: -long brecwrite(rec) mbuf rec;
                   2388: -{     long loc;
                   2389: -      int n;
                   2390: -      errno = 0;
                   2391: -      loc = lseek(curbf->dfd, 0L, 2);
                   2392: -      if((n = write(curbf->dfd, rec.mdata, rec.mlen)) == rec.mlen)
                   2393: -              return(loc);
                   2394: -      else if(n == -1 || errno)
                   2395: -              return(EOF);
                   2396: -      errno = BIOWRT;
                   2397: -      return(EOF);
                   2398: -}
                   2399: -
                   2400: -ndaddr newnode(b) hdr *b;
                   2401: -{     long loc;
                   2402: -      int n;
                   2403: -      b->hstamp = tranid;
                   2404: -      loc = lseek(curbf->tfd, 0L, 2);
                   2405: -      if(loc == -1)
                   2406: -              return(EOF);
                   2407: -      if((n = write(curbf->tfd, (char *)b, NDSZ)) != NDSZ)
                   2408: -              if(n < 0)
                   2409: -                      return(EOF);
                   2410: -              else {
                   2411: -                      errno = BIOWRT;
                   2412: -                      return(EOF);
                   2413: -              }
                   2414: -      return(loc/NDSZ);
                   2415: -}
                   2416: -
                   2417: -ndaddr oldnode(lev)
                   2418: -{     int n;
                   2419: -      ndaddr a;
                   2420: -      if(curbf->path[lev]->hstamp != tranid) {
                   2421: -              a = newnode(curbf->path[lev]);
                   2422: -              if(a == EOF)
                   2423: -                      curbf->fatal++;
                   2424: -              curbf->loc[lev] = a;
                   2425: -              return(a);
                   2426: -      }
                   2427: -      if(lseek(curbf->tfd, (long)curbf->loc[lev]*NDSZ, 0) == EOF)
                   2428: -              return(EOF);
                   2429: -      if((n = write(curbf->tfd, (char *)curbf->path[lev], NDSZ)) != NDSZ) {
                   2430: -              if(n >= 0)
                   2431: -                      errno = BIOWRT;
                   2432: -              return(EOF);
                   2433: -      }
                   2434: -      mustwrite(curbf, lev) = 0;
                   2435: -      return(curbf->loc[lev]);
                   2436: -}
                   2437: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:diskwrt.c\n"};
                   2438: -/*0100101010000110*/
                   2439: //GO.SYSIN DD diskwrt.c
                   2440: echo get.c 1>&2
                   2441: sed 's/.//' >get.c <<'//GO.SYSIN DD get.c'
                   2442: -#include "stdio.h"
                   2443: -#include "cbt.h"
                   2444: -extern bfile *bopen();
                   2445: -extern mbuf bkey();
                   2446: -
                   2447: -char *index;
                   2448: -char *dfile;
                   2449: -char sep = '!';
                   2450: -char preflg;
                   2451: -char nl;
                   2452: -
                   2453: -/* get key from index, print all records from dfile.
                   2454: - * default file names and separator in the index are as given
                   2455: - * preflg => prefix searching
                   2456: - */
                   2457: -char line[256];
                   2458: -char buf1[256], buf2[2048];
                   2459: -bfile *bi, *bd;
                   2460: -
                   2461: -main(argc, argv)
                   2462: -char **argv;
                   2463: -{     int i;
                   2464: -      char *p;
                   2465: -      for(i = 1; i < argc && *argv[i] == '-'; i++)
                   2466: -              for(p = argv[i] + 1; *(p-1) && *p; p++)
                   2467: -                      switch(*p) {
                   2468: -                      default:
                   2469: -                              fprintf(stderr, "unk flag %c\n", *p);
                   2470: -                              exit(1);
                   2471: -                      case 'p':
                   2472: -                              preflg = 1;
                   2473: -                              break;
                   2474: -                      case 'n':
                   2475: -                              nl = *++p;
                   2476: -                              break;
                   2477: -                      case 's':
                   2478: -                              sep = *++p;
                   2479: -                              break;
                   2480: -                      }
                   2481: -      if(i < argc) {
                   2482: -              dfile = argv[i++];
                   2483: -              bd = bopen(dfile, 0);
                   2484: -              if(bd == NULL) {
                   2485: -                      perror(dfile);
                   2486: -                      exit(1);
                   2487: -              }
                   2488: -      }
                   2489: -      if(i < argc) {
                   2490: -              index = argv[i++];
                   2491: -              bi = bopen(index, 0);
                   2492: -              if(bi == NULL) {
                   2493: -                      perror(index);
                   2494: -                      exit(1);
                   2495: -              }
                   2496: -      }
                   2497: -      for(;;) {
                   2498: -              (void) fgets(line, sizeof(line), stdin);
                   2499: -              if(feof(stdin))
                   2500: -                      exit(1);
                   2501: -              for(p = line; *p && *p != '\n'; p++)
                   2502: -                      ;
                   2503: -              if(*p == '\n')
                   2504: -                      *p = 0;
                   2505: -              if(index)
                   2506: -                      doindex();
                   2507: -              dodata();
                   2508: -      }
                   2509: -}
                   2510: -
                   2511: -doindex()
                   2512: -{     mbuf key, found, newkey, rec;
                   2513: -      int cnt;
                   2514: -      char *q;
                   2515: -      key.mlen = strlen(line);
                   2516: -      key.mdata = line;
                   2517: -      if(bseek(bi, key) == EOF) {
                   2518: -              printf("not found\n");
                   2519: -              return;
                   2520: -      }
                   2521: -      for(cnt = 0; ; cnt++) {
                   2522: -              if(bread(bi, &found, (mbuf *)NULL) == EOF)
                   2523: -                      break;
                   2524: -              if(found.mlen < key.mlen || strncmp(found.mdata, line, key.mlen)
                   2525: -                      break;
                   2526: -              if(!preflg && found.mdata[key.mlen] != sep)
                   2527: -                      break;
                   2528: -              for(q = found.mdata; q < found.mdata + found.mlen; q++)
                   2529: -                      if(*q == sep)
                   2530: -                              break;
                   2531: -              if(*q != sep) {
                   2532: -                      fprintf(stderr, "retrieved bad index:%s\n",
                   2533: -                              found.mdata);
                   2534: -                      continue;
                   2535: -              }
                   2536: -              newkey.mdata = ++q;
                   2537: -              newkey.mlen = found.mlen - (q - found.mdata);
                   2538: -              if(bseek(bd, newkey) != FOUND) {
                   2539: -                      fprintf(stderr, "erro, didn't find %s\n",
                   2540: -                              newkey.mdata);
                   2541: -                      continue;
                   2542: -              }
                   2543: -              bread(bd, (mbuf *)NULL &rec);
                   2544: -              for(i = 0; i < rec.mlen; i++)
                   2545: -                      if(rec.mdata[i] != nl)
                   2546: -                              putchar(rec.mdata[i]);
                   2547: -                      else
                   2548: -                              putchar('\n');
                   2549: -              putchar('\n');
                   2550: -      }
                   2551: -      if(cnt == 0)
                   2552: -              printf("not found\n");
                   2553: -}
                   2554: -/*1010001100101110*/
                   2555: //GO.SYSIN DD get.c
                   2556: echo lib.c 1>&2
                   2557: sed 's/.//' >lib.c <<'//GO.SYSIN DD lib.c'
                   2558: -#include "cbt.h"
                   2559: -mvgbt(to, from, ln) register char *from, *to;
                   2560: -{
                   2561: -      if(from > to)
                   2562: -              while(ln-- > 0) *to++ = *from++;
                   2563: -      else if(from < to)
                   2564: -      {       from += ln-1;
                   2565: -              to += ln-1;
                   2566: -              while(ln-- > 0) *to-- = *from--;
                   2567: -      }
                   2568: -}
                   2569: -
                   2570: -prnode(b)
                   2571: -hdr *b;
                   2572: -{     int i;
                   2573: -      char *p;
                   2574: -      dkey *d;
                   2575: -
                   2576: -      printf("kcnt %d htype %d hlev %d nfree %d ndsz %d\n", b->kcnt, b->htype,
                   2577: -              b->hlev, nfree(b), NDSZ);
                   2578: -      for(i = 0, p = (char *)(b+1); i < b->kcnt; i++) {
                   2579: -              d = (dkey *)p;
                   2580: -              prdkey(d);
                   2581: -              p += d->dlen;
                   2582: -      }
                   2583: -      putchar('\n');
                   2584: -}
                   2585: -
                   2586: -prdkey(d)
                   2587: -dkey *d;
                   2588: -{     int i;
                   2589: -      printf("(%d,%d,", d->dlen, d->dcom);
                   2590: -      for(i = 0; i < MAXKLEN &&i < d->dlen - DKEYSZ; i++) /* dlen unsigned */
                   2591: -              putchar(d->dkey[i]);
                   2592: -      printf("),");
                   2593: -}
                   2594: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:lib.c\n"};
                   2595: -/*1001101011001110*/
                   2596: //GO.SYSIN DD lib.c
                   2597: echo nodesz.c 1>&2
                   2598: sed 's/.//' >nodesz.c <<'//GO.SYSIN DD nodesz.c'
                   2599: -#include "cbt.h"
                   2600: -your nodesize is NDSZ bytes.  Except for checking,
                   2601: -nodesize should be the file system block size (cbt.h).
                   2602: -/*0100111000000100*/
                   2603: //GO.SYSIN DD nodesz.c
                   2604: echo prelim.c 1>&2
                   2605: sed 's/.//' >prelim.c <<'//GO.SYSIN DD prelim.c'
                   2606: -#include "stdio.h"
                   2607: -char line[129];
                   2608: -main()
                   2609: -{     unsigned short n;
                   2610: -      for(;;) {
                   2611: -              fgets(line, sizeof(line), stdin);
                   2612: -              if(feof(stdin))
                   2613: -                      break;
                   2614: -              n = strlen(line);
                   2615: -              n--;
                   2616: -              fwrite(&n, 1, sizeof(n), stdout);
                   2617: -              fwrite(line, 1, n, stdout);
                   2618: -              n = 0;
                   2619: -              fwrite(&n, 1, sizeof(n), stdout);
                   2620: -      }
                   2621: -}
                   2622: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/4/8:prelim.c\n"};
                   2623: -/*1011011100100111*/
                   2624: //GO.SYSIN DD prelim.c
                   2625: echo salvage.c 1>&2
                   2626: sed 's/.//' >salvage.c <<'//GO.SYSIN DD salvage.c'
                   2627: -/* write out all records pointed to by level 0 blocks,
                   2628: - * whether or not the level 0 blocks are accessible.
                   2629: - * the output is like that of bcat -R, except that many keys
                   2630: - * will be duplicated
                   2631: - * In general, the later keys are more up to date
                   2632: - * btsalvage xxx | slvg | sort | slvg2 | cbt build -R newxxx
                   2633: - * is the optimistic way of slavaging a b-tree in which the non-leaves
                   2634: - * have been clobbered
                   2635: - */
                   2636: -#include "cbt.h"
                   2637: -#include "pr.h"
                   2638: -#include "stdio.h"
                   2639: -
                   2640: -bfile         *curbf;
                   2641: -extern bfile  *newtran(), *xopen();
                   2642: -extern char   *malloc(), *strcpy(), *realloc();
                   2643: -extern long   lseek();
                   2644: -char keybuf[NDSZ];
                   2645: -char *recbuf;
                   2646: -int buflen;
                   2647: -
                   2648: -main(argc, argv)
                   2649: -char **argv;
                   2650: -{     bfile *bf;
                   2651: -      mbuf key, rec;
                   2652: -      int n;
                   2653: -      if(argc != 2) {
                   2654: -              fprintf(stderr, "usage: salvage file\n");
                   2655: -              exit(1);
                   2656: -      }
                   2657: -      bf = xopen(argv[1], 0);
                   2658: -      key.mdata = keybuf;
                   2659: -      if(bf == NULL) {
                   2660: -              fprintf(stderr, "couldn't open %s\n", argv[1]);
                   2661: -              exit(1);
                   2662: -      }
                   2663: -      while((n = breclen(bf)) > buflen) {
                   2664: -              if(buflen == 0)
                   2665: -                      recbuf = malloc(buflen = 1024);
                   2666: -              else
                   2667: -                      recbuf = realloc(recbuf, buflen += 1024);
                   2668: -              if(recbuf == NULL) {
                   2669: -                      fprintf(stderr, "recbuf[%d] failed\n", buflen);
                   2670: -                      exit(1);
                   2671: -              }
                   2672: -              rec.mdata = recbuf;
                   2673: -      }
                   2674: -      for(;;) {
                   2675: -              xread(bf, &key, &rec);
                   2676: -              write(1, (char *)&key.mlen, 2);
                   2677: -              write(1, key.mdata, key.mlen);
                   2678: -              write(1, (char *)&rec.mlen, 2);
                   2679: -              write(1, rec.mdata, rec.mlen);
                   2680: -      }
                   2681: -}
                   2682: -bfile *xopen(s, typ) char *s; /* typ is 0 or 2 */
                   2683: -{     bfile *p;
                   2684: -      int n, i;
                   2685: -
                   2686: -      p = alloc(bfile);
                   2687: -      if(p == NULL)
                   2688: -              goto nomem;
                   2689: -      n = strlen(s);
                   2690: -      p->fname = malloc((unsigned)n + 3);
                   2691: -      if(p->fname == NULL)
                   2692: -              goto nomem;
                   2693: -      (void) strcpy(p->fname, s);
                   2694: -      strcpy(p->fname + n, ".T");
                   2695: -      if((p->tfd = open(p->fname, typ)) == -1) {
                   2696: -              free(p->fname);
                   2697: -              free((char *)p);
                   2698: -              return(NULL);
                   2699: -      }
                   2700: -      p->rdwrt = typ;
                   2701: -      p->fatal = p->advnc = 0;
                   2702: -      p->altname = NULL;
                   2703: -      for(i = 0; i <= MXHT; i++) {
                   2704: -              p->path[i] = NULL;
                   2705: -              p->flag[i] = 0;
                   2706: -              p->loc[i] = 0;
                   2707: -      }
                   2708: -      p->path[0] = (hdr *)malloc(NDSZ);
                   2709: -      if(p->path[0] == NULL)
                   2710: -              goto nomem;
                   2711: -      curbf = p;
                   2712: -      if(read(p->tfd, (char *)p->path[0], NDSZ) != NDSZ) {
                   2713: -              perror(" first read");
                   2714: -              exit(1);
                   2715: -      }
                   2716: -      strcpy(p->fname + n, ".F");
                   2717: -      if(!treeonly(p) && (p->dfd = open(p->fname, typ)) == -1) {
                   2718: -              (void) close(p->tfd);
                   2719: -              free(p->fname);
                   2720: -              free(p->path[0]);
                   2721: -              free((char *)p);
                   2722: -              return(NULL);
                   2723: -      }
                   2724: -      else if(treeonly(p))
                   2725: -              p->dfd = -1;
                   2726: -      p->fname[n] = 0;
                   2727: -      p->height = p->path[0]->hlev;
                   2728: -      xfirst(p);
                   2729: -      return(p);
                   2730: -nomem:
                   2731: -      errno = BNOMEM;
                   2732: -      return(NULL);
                   2733: -}
                   2734: -
                   2735: -breclen(bf) bfile *bf;
                   2736: -{
                   2737: -      if(bf == NULL)
                   2738: -              return(EOF);
                   2739: -      if(notran(bf))
                   2740: -              return(EOF);
                   2741: -      if(bf->advnc)
                   2742: -              xadvance();
                   2743: -      if(bf->rdptr.rnum >= bf->path[0]->kcnt)
                   2744: -              return(EOF);
                   2745: -      if(treeonly(bf))
                   2746: -              return(0);
                   2747: -      return(lfadr(bf->path[0], bf->rdptr.rnum)->llen);
                   2748: -}
                   2749: -
                   2750: -xread(bf, key, rec) bfile *bf; mbuf *key, *rec;
                   2751: -{
                   2752: -      dkey *d;
                   2753: -      lfaddr *x;
                   2754: -      if(bf == NULL)
                   2755: -              return(NULL);
                   2756: -      if(notran(bf))
                   2757: -              return(EOF);
                   2758: -      if(bf->advnc)
                   2759: -              xadvance();
                   2760: -      if(bf->rdptr.rnum >= bf->path[0]->kcnt)
                   2761: -              return(EOF);
                   2762: -      if(key != NULL) {
                   2763: -              d = bf->rdptr.rptr;
                   2764: -              key->mlen = d->dlen - DKEYSZ + d->dcom;
                   2765: -              mvgbt(key->mdata, bf->rdptr.rpref, d->dcom);
                   2766: -              mvgbt(key->mdata + d->dcom, d->dkey, d->dlen - DKEYSZ);
                   2767: -      }
                   2768: -      if(rec != NULL && !treeonly(bf)) {
                   2769: -              x = lfadr(bf->path[0], bf->rdptr.rnum);
                   2770: -              rec->mlen = x->llen;
                   2771: -              if(rec->mlen != 0) {
                   2772: -                      (void) lseek(bf->dfd, x->lloc, 0);
                   2773: -                      (void) read(bf->dfd, rec->mdata, (int)rec->mlen);
                   2774: -              }
                   2775: -              /* errors on read ? */
                   2776: -      }
                   2777: -      bf->advnc = 1;
                   2778: -      return(0);
                   2779: -}
                   2780: -
                   2781: -xstep(level)
                   2782: -/* ran off the end of node at lev-1 */
                   2783: -{     hdr *b;
                   2784: -      int n, i;
                   2785: -      ndaddr u;
                   2786: -      do {
                   2787: -              n = read(curbf->tfd, (char *)curbf->path[0], NDSZ);
                   2788: -              if(n == 0)
                   2789: -                      exit(0);
                   2790: -              if(n != NDSZ) {
                   2791: -                      perror("xstep");
                   2792: -                      exit(1);
                   2793: -              }
                   2794: -      } while(curbf->path[0]->hlev != 0);
                   2795: -}
                   2796: -
                   2797: -xadvance()
                   2798: -{     mbuf x;
                   2799: -      dkey *dold, *dnew;
                   2800: -      struct rdptr *y = &curbf->rdptr;
                   2801: -      curbf->advnc = 0;
                   2802: -      dold = y->rptr;
                   2803: -      if(++y->rnum < curbf->path[0]->kcnt) {
                   2804: -              dnew = (dkey *)((char *)dold + dold->dlen);
                   2805: -              if(dold->dcom < dnew->dcom)
                   2806: -                      mvgbt(y->rpref + dold->dcom, dold->dkey, dnew->dcom - dold->dcom);
                   2807: -              y->rptr = dnew;
                   2808: -              return;
                   2809: -      }
                   2810: -      if(xstep(1) == EOF) {
                   2811: -              y->rnum = curbf->path[0]->kcnt + 1;
                   2812: -              y->rptr  = NULL;
                   2813: -      }
                   2814: -      else {
                   2815: -              y->rnum = 0;
                   2816: -              y->rptr = (dkey *)(curbf->path[0] + 1);
                   2817: -      }
                   2818: -}
                   2819: -
                   2820: -xfirst(p)
                   2821: -bfile *p;
                   2822: -{     int n;
                   2823: -      while(p->path[0]->hlev != 0) {
                   2824: -              n = read(p->tfd, (char *)p->path[0], NDSZ);
                   2825: -              if(n == 0) {
                   2826: -                      fprintf(stderr, "empty?\n");
                   2827: -                      exit(0);
                   2828: -              }
                   2829: -              if(n != NDSZ) {
                   2830: -                      perror("xfirst");
                   2831: -                      exit(1);
                   2832: -              }
                   2833: -      }
                   2834: -      curbf->rdptr.rnum = 0;
                   2835: -      curbf->rdptr.rptr = (dkey *)(curbf->path[0] + 1);
                   2836: -}
                   2837: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:salvage.c\n"};
                   2838: -/*0000110110110000*/
                   2839: //GO.SYSIN DD salvage.c
                   2840: echo seek.c 1>&2
                   2841: sed 's/.//' >seek.c <<'//GO.SYSIN DD seek.c'
                   2842: -#include "cbt.h"
                   2843: -#include "pr.h"
                   2844: -
                   2845: -extern bfile  *curbf;
                   2846: -
                   2847: -xscan(b, key, x) hdr *b; mbuf key; private *x;
                   2848: -{     int ncom, i, n, val;
                   2849: -      char a, *p;
                   2850: -      dkey *d;
                   2851: -
                   2852: -      n = i = ncom = 0;
                   2853: -      val = NOTFOUND;
                   2854: -      p = (char *)(b+1);
                   2855: -      d = (dkey *)p;
                   2856: -      for(; i < b->kcnt; i++, p += d->dlen) {
                   2857: -              d = (dkey *)p;
                   2858: -              if(ncom < d->dcom)
                   2859: -                      goto onward;
                   2860: -              if(ncom > d->dcom) {
                   2861: -                      if(x != NULL) {
                   2862: -                              x->match = val;
                   2863: -                              x->ncom = d->dcom;
                   2864: -                              x->ocom = ncom;
                   2865: -                              x->d = d;
                   2866: -                      }
                   2867: -                      return(i);
                   2868: -              }
                   2869: -              for(n = ncom; ncom < key.mlen && ncom - n < d->dlen - DKEYSZ; ncom++) {
                   2870: -                      if((a = d->dkey[ncom - n]) == key.mdata[ncom])
                   2871: -                              continue;
                   2872: -                      if(a < key.mdata[ncom])
                   2873: -                              goto onward;
                   2874: -                      goto done;
                   2875: -              }
                   2876: -              if(ncom == key.mlen) {
                   2877: -                      if(ncom == d->dlen - DKEYSZ + d->dcom)
                   2878: -                              val = FOUND;
                   2879: -                      goto done;
                   2880: -              }
                   2881: -      onward: ;
                   2882: -      }
                   2883: -/* infinity: */
                   2884: -      if(x != NULL) {
                   2885: -              x->match = EOF;
                   2886: -              x->ncom = ncom;
                   2887: -              x->ocom = n;
                   2888: -              x->d = d;
                   2889: -      }
                   2890: -      return(i);
                   2891: -done:
                   2892: -      if(x != NULL) {
                   2893: -              x->match = val;
                   2894: -              x->ncom = ncom;
                   2895: -              x->ocom = n;
                   2896: -              x->d = d;
                   2897: -      }
                   2898: -      return(i);
                   2899: -}
                   2900: -
                   2901: -desce(bf, key, x) bfile *bf; mbuf key; private *x;
                   2902: -{     int i, j;
                   2903: -      ndaddr u;
                   2904: -      for(i = bf->height; i > 0; i--) {
                   2905: -              j = xscan(bf->path[i], key, (private *)NULL);
                   2906: -              u = *ndadr(bf->path[i], j);
                   2907: -              if(bf->loc[i-1] != u)
                   2908: -                      if(getincore(i - 1, u) == EOF)
                   2909: -                              return(EOF);
                   2910: -      }
                   2911: -      i = xscan(bf->path[0], key, x);
                   2912: -      return(i);
                   2913: -}
                   2914: -
                   2915: -step(level)
                   2916: -/* ran off the end of node at lev-1 */
                   2917: -{     hdr *b;
                   2918: -      int n, i;
                   2919: -      ndaddr u;
                   2920: -      if(level > curbf->height)
                   2921: -              return(EOF);
                   2922: -      n = curbf->loc[level - 1];
                   2923: -      b = curbf->path[level];
                   2924: -      for(i = 0; i <= b->kcnt; i++)
                   2925: -              if(*ndadr(b, i) == n)
                   2926: -                      break;
                   2927: -      if(i >= b->kcnt)
                   2928: -              return(step(level + 1));
                   2929: -      n = level;
                   2930: -      i++;
                   2931: -      do {
                   2932: -              u = *ndadr(curbf->path[n], i);
                   2933: -              if(curbf->loc[n-1] != u)
                   2934: -                      if(getincore(n - 1, u) == EOF)
                   2935: -                              return(EOF);
                   2936: -              i = 0;
                   2937: -      } while(--n > 0);
                   2938: -      return(0);
                   2939: -}
                   2940: -
                   2941: -advance()
                   2942: -{     dkey *dold, *dnew;
                   2943: -      struct rdptr *y = &curbf->rdptr;
                   2944: -      curbf->advnc = 0;
                   2945: -      dold = y->rptr;
                   2946: -      if(++y->rnum < curbf->path[0]->kcnt) {
                   2947: -              dnew = (dkey *)((char *)dold + dold->dlen);
                   2948: -              if(dold->dcom < dnew->dcom)
                   2949: -                      mvgbt(y->rpref + dold->dcom, dold->dkey, dnew->dcom - dold->dcom);
                   2950: -              y->rptr = dnew;
                   2951: -              return(0);
                   2952: -      }
                   2953: -      errno = 0;
                   2954: -      if(step(1) == EOF) {
                   2955: -              if(errno)
                   2956: -                      return(EOF);
                   2957: -              y->rnum = curbf->path[0]->kcnt + 1;
                   2958: -              y->rptr  = NULL;
                   2959: -      }
                   2960: -      else {
                   2961: -              y->rnum = 0;
                   2962: -              y->rptr = (dkey *)(curbf->path[0] + 1);
                   2963: -      }
                   2964: -      return(0);
                   2965: -}
                   2966: -static struct D { struct D *a; char *b;} VER = {&VER,"\n82/10/9:seek.c\n"};
                   2967: -/*1100011110101111*/
                   2968: -/*1101111110111111*/
                   2969: //GO.SYSIN DD seek.c
                   2970: echo slvg.c 1>&2
                   2971: sed 's/.//' >slvg.c <<'//GO.SYSIN DD slvg.c'
                   2972: -#include "stdio.h"
                   2973: -/* change the output of btsalvage or btcat -R to sortable */
                   2974: -/* an 8 byte sortable sequence number is appended to each key
                   2975: - * that slvg2 can keep only the last record with a given key */
                   2976: -
                   2977: -char *buf;
                   2978: -int buflen;
                   2979: -long reccnt;
                   2980: -extern char *malloc(), *realloc();
                   2981: -
                   2982: -main()
                   2983: -{     int n, i, j;
                   2984: -      for(;;) {
                   2985: -              if(read(0, &n, 2) == 0)
                   2986: -                      exit(0);
                   2987: -              if(n > buflen)
                   2988: -                      space(n);
                   2989: -              read(0, buf, n);
                   2990: -              reccnt++;
                   2991: -              out(buf, n, '\t');
                   2992: -              countout();
                   2993: -              read(0, &n, 2);
                   2994: -              if(n > buflen)
                   2995: -                      space(n);
                   2996: -              read(0, buf, n);
                   2997: -              j = n;
                   2998: -              for(i = 0; i < 4; i++) {
                   2999: -                      putchar('a' + (j & 0xf));
                   3000: -                      j >>= 4;
                   3001: -              }
                   3002: -              out(buf, n, '\n');
                   3003: -      }
                   3004: -}
                   3005: -
                   3006: -space(n)
                   3007: -{
                   3008: -      while(n > buflen) {
                   3009: -              if(buflen == 0)
                   3010: -                      buf = malloc(buflen = 1024);
                   3011: -              else
                   3012: -                      buf = realloc(buf, buflen += 1024);
                   3013: -              if(buf == 0) {
                   3014: -                      fprintf(stderr, "buf[%d]failed\n", buflen);
                   3015: -                      exit(1);
                   3016: -              }
                   3017: -              
                   3018: -      }
                   3019: -}
                   3020: -
                   3021: -out(s, n, c)
                   3022: -char *s;
                   3023: -{
                   3024: -      while(n-- > 0) {
                   3025: -              putchar('3' + ((*s >> 6) & 3));
                   3026: -              putchar((*s & 077) + ' ');
                   3027: -              s++;
                   3028: -      }
                   3029: -      putchar(c);
                   3030: -}
                   3031: -
                   3032: -countout()
                   3033: -{     int i, n;
                   3034: -      n = reccnt;
                   3035: -      for(i = 7; i >= 0; i--)
                   3036: -              putchar('0' + ((n >> (4*i)) & 077));
                   3037: -}
                   3038: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/7:slvg.c\n"};
                   3039: -/*1100100010001010*/
                   3040: //GO.SYSIN DD slvg.c
                   3041: echo slvg2.c 1>&2
                   3042: sed 's/.//' >slvg2.c <<'//GO.SYSIN DD slvg2.c'
                   3043: -/* takes the output fromt slvg | sort and puts it back into
                   3044: - * form suitable for btbuild -R
                   3045: - * it reduces the two byte codes, and it only keeps the
                   3046: - * last version of each record.
                   3047: - * the input format is
                   3048: - * key tab 8-bytes-of-sequence 4-byete-of-value-len value newline
                   3049: - */
                   3050: -#include "stdio.h"
                   3051: -#define BUF   20000
                   3052: -char bufa[BUF], bufb[BUF];
                   3053: -char *old = bufa;
                   3054: -char *new = bufb;
                   3055: -int len;
                   3056: -
                   3057: -main()
                   3058: -{     char *p, *q;
                   3059: -      int c, i;
                   3060: -loop:
                   3061: -      for(p = new; (c = getchar()) != '\t' && c != EOF; *p++ = c)
                   3062: -              if(p - new >= BUF) {
                   3063: -                      fprintf(stderr, "recompile slvg2 with more BUF\n");
                   3064: -                      exit(1);
                   3065: -              }
                   3066: -      if(c == EOF)
                   3067: -              exit(0);
                   3068: -      *p++ = 0;
                   3069: -      for(i = 0; i < 8; i++)
                   3070: -              getchar();
                   3071: -      if((p - new != len || strcmp(old, new) != 0) && len > 0) {
                   3072: -              out(old);
                   3073: -              dorest();
                   3074: -      }
                   3075: -      len = p - new;
                   3076: -      q = old;
                   3077: -      old = new;
                   3078: -      new = q;
                   3079: -      ignore();
                   3080: -      goto loop;
                   3081: -}
                   3082: -
                   3083: -out(s)
                   3084: -char *s;
                   3085: -{     short n;
                   3086: -      char c;
                   3087: -      n = (len - 1)/2;
                   3088: -      fwrite((char *)&n, 1, 2, stdout);
                   3089: -      for(; *s; s++) {
                   3090: -              c = (*s - '3') << 6;
                   3091: -              c |= *++s- ' ';
                   3092: -              putchar(c);
                   3093: -      }
                   3094: -}
                   3095: -
                   3096: -ignore()
                   3097: -{     int c;
                   3098: -      while((c = getchar()) != '\n' && c != EOF)
                   3099: -              ;
                   3100: -      if(c == EOF)
                   3101: -              exit(0);
                   3102: -}
                   3103: -
                   3104: -dorest()
                   3105: -{     unsigned short n;
                   3106: -      int i;
                   3107: -      /* 4 bytes of length */
                   3108: -      for(i = n = 0; i < 4; i++)
                   3109: -              n |= (getchar() - 'a') << (4*i);
                   3110: -      fwrite((char *)&n, 1, 2, stdout);
                   3111: -      while((i = getchar()) != '\n' && i != EOF) {
                   3112: -              n = (i - '3') << 6;
                   3113: -              n |= getchar() - ' ';
                   3114: -              putchar(n);
                   3115: -      }
                   3116: -}
                   3117: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:slvg2.c\n"};
                   3118: -/*0010100001111110*/
                   3119: -/*1110001101011101*/
                   3120: //GO.SYSIN DD slvg2.c
                   3121: echo tran.c 1>&2
                   3122: sed 's/.//' >tran.c <<'//GO.SYSIN DD tran.c'
                   3123: -/* place holders */
                   3124: -#include "cbt.h"
                   3125: -extern long time();
                   3126: -long tranid;
                   3127: -
                   3128: -long getlpid()
                   3129: -{
                   3130: -      return(time((long *)0) ^ 077777 + getpid());
                   3131: -}
                   3132: -extern bfile *curbf;
                   3133: -bfile *newtran(bf) bfile *bf;
                   3134: -{
                   3135: -      tranid = getlpid();
                   3136: -      return(bf);
                   3137: -}
                   3138: -
                   3139: -notran(bf) bfile *bf;
                   3140: -{
                   3141: -      curbf = bf;
                   3142: -      if(bf->fatal) {
                   3143: -              if(bf->fatal++ < 2) {
                   3144: -                      errno = BFATAL;
                   3145: -                      return(EOF);
                   3146: -              }
                   3147: -              perror("btree repeatedly accessed after fatal error");
                   3148: -              abort();
                   3149: -      }
                   3150: -      return(0);
                   3151: -}
                   3152: -
                   3153: -trabort()
                   3154: -{
                   3155: -      errno = BUTRAN;
                   3156: -      tranid = 0;
                   3157: -}
                   3158: -
                   3159: -intran()
                   3160: -{
                   3161: -      return(0);
                   3162: -}
                   3163: -
                   3164: -rmtran(bf) bfile *bf;
                   3165: -{
                   3166: -}
                   3167: -static struct D { struct D *a; char *b;} VER = {&VER,"\n81/8/9:tran.c\n"};
                   3168: -/*0001010110001011*/
                   3169: //GO.SYSIN DD tran.c
                   3170: echo makefile 1>&2
                   3171: sed 's/.//' >makefile <<'//GO.SYSIN DD makefile'
                   3172: -.SUFFIXES:    .x .o .c
                   3173: -.c.o:
                   3174: -      $(CC) $(CFLAGS) -c $<
                   3175: -      -ld -r -X $@
                   3176: -      mv a.out $@
                   3177: -.c.x:
                   3178: -      $(CC) $(CFLAGS) -c $<
                   3179: -      -ld -r -X $*.o
                   3180: -      mv a.out $*.o
                   3181: -      ar u btlib $*.o
                   3182: -      rm $*.o
                   3183: -      touch $*.x
                   3184: -CFLAGS=-g
                   3185: -debug:        bttest
                   3186: -all:  nodesize
                   3187: -all:  btlib btcat btbuild bttest btcreat btreport btsquash btran btdelete
                   3188: -all:  btadd btdiag btexer
                   3189: -bwrite.x bdelete.x diskrd.x diskwrt.x bt.x seek.x tran.x:     cbt.h
                   3190: -btsquash.o btcreat.o btreport.o bttest.o btcat.o btbuild.o:   cbt.h
                   3191: -btlib:        bt.x seek.x tran.x diskrd.x diskwrt.x bwrite.x bdelete.x lib.x
                   3192: -      ranlib btlib
                   3193: -cyntax:
                   3194: -      cyntax bttest.c bt.c seek.c tran.c diskrd.c diskwrt.c bwrite.c bdelete.c lib.c
                   3195: -bttest:       bttest.o btlib
                   3196: -      $(CC) $(CFLAGS) -o bttest bttest.o btlib
                   3197: -btran:        btran.o
                   3198: -      $(CC) $(CFLAGS) -o btran btran.o
                   3199: -btsquash:     btsquash.o btlib
                   3200: -      $(CC) $(CFLAGS) -o btsquash btsquash.o btlib
                   3201: -btadd:        btadd.o btlib
                   3202: -      $(CC) $(CFLAGS) -o btadd btadd.o btlib
                   3203: -btreport:     btreport.o btlib
                   3204: -      $(CC) $(CFLAGS) -o btreport btreport.o btlib
                   3205: -btdelete:     btdelete.o btlib
                   3206: -      $(CC) $(CFLAGS) -o btdelete btdelete.o btlib
                   3207: -btcreat:      btcreat.o cbt.h
                   3208: -      $(CC) $(CFLAGS) -o btcreat btcreat.o btlib
                   3209: -btdiag:       btdiag.o btlib
                   3210: -      $(CC) $(CFLAGS) -o btdiag btdiag.o btlib
                   3211: -btexer:       btexer.o btlib
                   3212: -      $(CC) $(CFLAGS) -o btexer btexer.o btlib
                   3213: -btcat:        btcat.o btlib
                   3214: -      cc -o btcat btcat.o btlib
                   3215: -btbuild:      btbuild.o lib.x
                   3216: -      $(CC) $(CFLAGS) -o btbuild btbuild.o btlib
                   3217: -nodesize:
                   3218: -      @cc -E $(CFLAGS) nodesz.c | grep nodesize
                   3219: -install:
                   3220: -      -cp cbt /usr/bin
                   3221: -      -cp cbt.h /usr/include
                   3222: -      -cp btlib /usr/lib/libcbt.a
                   3223: -      -ranlib /usr/lib/libcbt.a
                   3224: -clean:
                   3225: -      rm *.o *.x btlib
                   3226: //GO.SYSIN DD makefile
                   3227: echo cbt 1>&2
                   3228: sed 's/.//' >cbt <<'//GO.SYSIN DD cbt'
                   3229: -LIB=/usr/lib/btree
                   3230: -if test $# = 0
                   3231: -then
                   3232: -      echo 'cbt add|build|cat|creat|delete|report|squash ...'
                   3233: -      exit 1
                   3234: -fi
                   3235: -x=$1
                   3236: -shift
                   3237: -case $x in
                   3238: -add)  case $1 in
                   3239: -      -*)     shift
                   3240: -              $LIB/btadd $* ;;
                   3241: -      *)      $LIB/btran | $LIB/btadd $* ;;
                   3242: -      esac ;;
                   3243: -build)        case $1 in
                   3244: -      -*)     shift
                   3245: -              $LIB/btbuild $* ;;
                   3246: -      *)      $LIB/btran | $LIB/btbuild $* ;;
                   3247: -      esac ;;
                   3248: -cat)  $LIB/btcat $* ;;
                   3249: -creat)        $LIB/btcreat $* ;;
                   3250: -delete)       case $1 in
                   3251: -      -*)     shift
                   3252: -              $LIB/btdelete $* ;;
                   3253: -      *)      $LIB/btran | $LIB/btdelete $* ;;
                   3254: -      esac ;;
                   3255: -grep) $LIB/btgrep $* ;;
                   3256: -report)       $LIB/btreport $* ;;
                   3257: -squash)       if test $# != 1
                   3258: -      then
                   3259: -              echo usage cbt squash file-name
                   3260: -              exit 1
                   3261: -      fi
                   3262: -      $LIB/btsquash $1 ;;
                   3263: -*)    echo 1>&2 unknown command $x
                   3264: -esac
                   3265: //GO.SYSIN DD cbt
                   3266: echo verify 1>&2
                   3267: sed 's/.//' >verify <<'//GO.SYSIN DD verify'
                   3268: -PATH=:$PATH
                   3269: -export PATH
                   3270: -x=$1
                   3271: -if test $# = 0
                   3272: -then
                   3273: -      echo verify rec-cnt
                   3274: -      exit 1
                   3275: -fi
                   3276: -echo 1. loading a btree with $x records
                   3277: -btcreat junk
                   3278: -awk '{for(i = 0; i < $1; i++) printf "%8.8d\n", i}' <<! | btran | btbuild junk
                   3279: -$x
                   3280: -!
                   3281: -echo 1. does btreport think there are $x records
                   3282: -btreport junk
                   3283: -echo 2. if btcat doesn\'t agree, it will say so
                   3284: -btcat junk | awk 'length != 9 || $0+0 != NR-1 {print length, $0+0, NR, "bad"}'
                   3285: -echo 2. end of load test
                   3286: -echo
                   3287: -echo 3. delete all the records
                   3288: -awk '{for(i = 0; i < $1; i++) printf "%8.8d\n", i}' <<! | btdelete junk
                   3289: -$x
                   3290: -!
                   3291: -echo 3. btreport should think they are all gone
                   3292: -btreport junk
                   3293: -echo 4. btcat should too
                   3294: -btcat junk | awk '{next}; END {print NR " records"}'
                   3295: -echo 4. there should be no records left
                   3296: -echo
                   3297: -echo 5. now load them back one at a time
                   3298: -echo $x | awk '{for(i = 0; i < $1; i++) printf "%8.8d\n", i}' |
                   3299: -      btran | tee foo | btadd junk
                   3300: -echo 5. btreport should think there are $x records
                   3301: -btreport junk
                   3302: -echo 6. btcat should think so too
                   3303: -btcat junk | awk 'length != 9 || $0+0 != NR-1 {print length, $0+0, NR, "bad"}
                   3304: -      END {print NR " records"}'
                   3305: -echo 6. there should have been no bad records
                   3306: -echo
                   3307: -echo 7. now throw every other one away
                   3308: -awk '{for(i = 0; i < $1; i+=2) printf "%8.8d\n", i}' <<! | btdelete junk
                   3309: -$x
                   3310: -!
                   3311: -echo 7. btreport should think they are gone
                   3312: -btreport junk
                   3313: -echo 8. btcat should too
                   3314: -btcat junk | awk '{next}; END {print NR " records"}'
                   3315: -echo 8. there should be half the records left
                   3316: -echo
                   3317: -echo 9. now squash the file
                   3318: -btsquash junk
                   3319: -echo 9. btreport says
                   3320: -btreport junk
                   3321: -echo 10. and can btcat find them all:
                   3322: -btcat junk | awk 'length != 9 || $0+0 != 2*NR-1 {print length, $0+0, NR, "bad"}
                   3323: -      END {print NR " records"}'
                   3324: -echo 10. there should be half the records left
                   3325: -echo
                   3326: -echo 11. now put the other half back
                   3327: -echo $x | awk '{for(i = 0; i < $1; i+=2) printf "%8.8d\n", i}' |
                   3328: -      btran | btadd junk
                   3329: -echo 11. btreport should see $x records
                   3330: -btreport junk
                   3331: -echo 12. so should btcat
                   3332: -btcat junk | awk 'length != 9 || $0+0 != NR-1 {print length, $0+0, NR, "bad"}
                   3333: -      END {print NR " records"}'
                   3334: -echo 13. and they should all be there after squashing
                   3335: -btsquash junk
                   3336: -echo 13. btreport should see $x records
                   3337: -btreport junk
                   3338: -echo 14. so should btcat
                   3339: -btcat junk | awk 'length != 9 || $0+0 != NR-1 {print length, $0+0, NR, "bad"}
                   3340: -      END {print NR " records"}'
                   3341: -echo and that is all I could think of doing
                   3342: //GO.SYSIN DD verify
                   3343: echo README 1>&2
                   3344: sed 's/.//' >README <<'//GO.SYSIN DD README'
                   3345: -INSTALLING THE BTREE STUFF
                   3346: -Acceptance testing -
                   3347: -1.  Put the distributed software in a testing directory.
                   3348: -      Put the name of the directory in the LIB=  line in cbt.
                   3349: -      make all. (If you are not on a vax, remove the -g CFLAG in makefile.)
                   3350: -      (If your machine does not have ranlib, remove all references
                   3351: -      to it from the makefile.)
                   3352: -2.  Run the verify shell script with various arguments.  I use
                   3353: -      verify 10, verify 100, and verify 1000.  The last needs 3 minutes
                   3354: -      of cpu time.
                   3355: -3.  Copy everything to its final directory.  Fix the CFLAGS line in
                   3356: -      the makefile by removing -DTEST.  Change the LIB= line in cbt
                   3357: -      to point to this directory.  Change the NDSZ definition after
                   3358: -      #else in cbt.h to the size of a file system block on your system
                   3359: -      (512 or 1024 or whatever).
                   3360: -4.  make clean
                   3361: -      make all
                   3362: -      Run the verify shell script to check that everything is still ok.
                   3363: -5.  make install
                   3364: //GO.SYSIN DD README

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.