|
|
1.1 ! root 1: /* write out all records pointed to by level 0 blocks, ! 2: * whether or not the level 0 blocks are accessible. ! 3: * the output is like that of bcat -R, except that many keys ! 4: * will be duplicated ! 5: * In general, the later keys are more up to date ! 6: * btsalvage xxx | slvg | sort | slvg2 | cbt build -R newxxx ! 7: * is the optimistic way of slavaging a b-tree in which the non-leaves ! 8: * have been clobbered ! 9: */ ! 10: #include "cbt.h" ! 11: #include "pr.h" ! 12: #include "stdio.h" ! 13: ! 14: bfile *curbf; ! 15: extern bfile *newtran(), *xopen(); ! 16: extern char *malloc(), *strcpy(), *realloc(); ! 17: extern long lseek(); ! 18: char keybuf[NDSZ]; ! 19: char *recbuf; ! 20: int buflen; ! 21: ! 22: main(argc, argv) ! 23: char **argv; ! 24: { bfile *bf; ! 25: mbuf key, rec; ! 26: int n; ! 27: if(argc != 2) { ! 28: fprintf(stderr, "usage: salvage file\n"); ! 29: exit(1); ! 30: } ! 31: bf = xopen(argv[1], 0); ! 32: key.mdata = keybuf; ! 33: if(bf == NULL) { ! 34: fprintf(stderr, "couldn't open %s\n", argv[1]); ! 35: exit(1); ! 36: } ! 37: while((n = breclen(bf)) > buflen) { ! 38: if(buflen == 0) ! 39: recbuf = malloc(buflen = 1024); ! 40: else ! 41: recbuf = realloc(recbuf, buflen += 1024); ! 42: if(recbuf == NULL) { ! 43: fprintf(stderr, "recbuf[%d] failed\n", buflen); ! 44: exit(1); ! 45: } ! 46: rec.mdata = recbuf; ! 47: } ! 48: for(;;) { ! 49: xread(bf, &key, &rec); ! 50: write(1, (char *)&key.mlen, 2); ! 51: write(1, key.mdata, key.mlen); ! 52: write(1, (char *)&rec.mlen, 2); ! 53: write(1, rec.mdata, rec.mlen); ! 54: } ! 55: } ! 56: bfile *xopen(s, typ) char *s; /* typ is 0 or 2 */ ! 57: { bfile *p; ! 58: int n, i; ! 59: ! 60: p = alloc(bfile); ! 61: if(p == NULL) ! 62: goto nomem; ! 63: n = strlen(s); ! 64: p->fname = malloc((unsigned)n + 3); ! 65: if(p->fname == NULL) ! 66: goto nomem; ! 67: (void) strcpy(p->fname, s); ! 68: strcpy(p->fname + n, ".T"); ! 69: if((p->tfd = open(p->fname, typ)) == -1) { ! 70: free(p->fname); ! 71: free((char *)p); ! 72: return(NULL); ! 73: } ! 74: p->rdwrt = typ; ! 75: p->fatal = p->advnc = 0; ! 76: p->altname = NULL; ! 77: for(i = 0; i <= MXHT; i++) { ! 78: p->path[i] = NULL; ! 79: p->flag[i] = 0; ! 80: p->loc[i] = 0; ! 81: } ! 82: p->path[0] = (hdr *)malloc(NDSZ); ! 83: if(p->path[0] == NULL) ! 84: goto nomem; ! 85: curbf = p; ! 86: if(read(p->tfd, (char *)p->path[0], NDSZ) != NDSZ) { ! 87: perror(" first read"); ! 88: exit(1); ! 89: } ! 90: strcpy(p->fname + n, ".F"); ! 91: if(!treeonly(p) && (p->dfd = open(p->fname, typ)) == -1) { ! 92: (void) close(p->tfd); ! 93: free(p->fname); ! 94: free(p->path[0]); ! 95: free((char *)p); ! 96: return(NULL); ! 97: } ! 98: else if(treeonly(p)) ! 99: p->dfd = -1; ! 100: p->fname[n] = 0; ! 101: p->height = p->path[0]->hlev; ! 102: xfirst(p); ! 103: return(p); ! 104: nomem: ! 105: errno = BNOMEM; ! 106: return(NULL); ! 107: } ! 108: ! 109: breclen(bf) bfile *bf; ! 110: { ! 111: if(bf == NULL) ! 112: return(EOF); ! 113: if(notran(bf)) ! 114: return(EOF); ! 115: if(bf->advnc) ! 116: xadvance(); ! 117: if(bf->rdptr.rnum >= bf->path[0]->kcnt) ! 118: return(EOF); ! 119: if(treeonly(bf)) ! 120: return(0); ! 121: return(lfadr(bf->path[0], bf->rdptr.rnum)->llen); ! 122: } ! 123: ! 124: xread(bf, key, rec) bfile *bf; mbuf *key, *rec; ! 125: { ! 126: dkey *d; ! 127: lfaddr *x; ! 128: if(bf == NULL) ! 129: return(NULL); ! 130: if(notran(bf)) ! 131: return(EOF); ! 132: if(bf->advnc) ! 133: xadvance(); ! 134: if(bf->rdptr.rnum >= bf->path[0]->kcnt) ! 135: return(EOF); ! 136: if(key != NULL) { ! 137: d = bf->rdptr.rptr; ! 138: key->mlen = d->dlen - DKEYSZ + d->dcom; ! 139: mvgbt(key->mdata, bf->rdptr.rpref, d->dcom); ! 140: mvgbt(key->mdata + d->dcom, d->dkey, d->dlen - DKEYSZ); ! 141: } ! 142: if(rec != NULL && !treeonly(bf)) { ! 143: x = lfadr(bf->path[0], bf->rdptr.rnum); ! 144: rec->mlen = x->llen; ! 145: if(rec->mlen != 0) { ! 146: (void) lseek(bf->dfd, x->lloc, 0); ! 147: (void) read(bf->dfd, rec->mdata, (int)rec->mlen); ! 148: } ! 149: /* errors on read ? */ ! 150: } ! 151: bf->advnc = 1; ! 152: return(0); ! 153: } ! 154: ! 155: xstep(level) ! 156: /* ran off the end of node at lev-1 */ ! 157: { hdr *b; ! 158: int n, i; ! 159: ndaddr u; ! 160: do { ! 161: n = read(curbf->tfd, (char *)curbf->path[0], NDSZ); ! 162: if(n == 0) ! 163: exit(0); ! 164: if(n != NDSZ) { ! 165: perror("xstep"); ! 166: exit(1); ! 167: } ! 168: } while(curbf->path[0]->hlev != 0); ! 169: } ! 170: ! 171: xadvance() ! 172: { mbuf x; ! 173: dkey *dold, *dnew; ! 174: struct rdptr *y = &curbf->rdptr; ! 175: curbf->advnc = 0; ! 176: dold = y->rptr; ! 177: if(++y->rnum < curbf->path[0]->kcnt) { ! 178: dnew = (dkey *)((char *)dold + dold->dlen); ! 179: if(dold->dcom < dnew->dcom) ! 180: mvgbt(y->rpref + dold->dcom, dold->dkey, dnew->dcom - dold->dcom); ! 181: y->rptr = dnew; ! 182: return; ! 183: } ! 184: if(xstep(1) == EOF) { ! 185: y->rnum = curbf->path[0]->kcnt + 1; ! 186: y->rptr = NULL; ! 187: } ! 188: else { ! 189: y->rnum = 0; ! 190: y->rptr = (dkey *)(curbf->path[0] + 1); ! 191: } ! 192: } ! 193: ! 194: xfirst(p) ! 195: bfile *p; ! 196: { int n; ! 197: while(p->path[0]->hlev != 0) { ! 198: n = read(p->tfd, (char *)p->path[0], NDSZ); ! 199: if(n == 0) { ! 200: fprintf(stderr, "empty?\n"); ! 201: exit(0); ! 202: } ! 203: if(n != NDSZ) { ! 204: perror("xfirst"); ! 205: exit(1); ! 206: } ! 207: } ! 208: curbf->rdptr.rnum = 0; ! 209: curbf->rdptr.rptr = (dkey *)(curbf->path[0] + 1); ! 210: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.