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