1*5e96a66cSDavid du Colombier #include "stdinc.h" 2*5e96a66cSDavid du Colombier #include "dat.h" 3*5e96a66cSDavid du Colombier #include "fns.h" 4*5e96a66cSDavid du Colombier #include "error.h" 5*5e96a66cSDavid du Colombier 6*5e96a66cSDavid du Colombier /* 7*5e96a66cSDavid du Colombier * integer conversion routines 8*5e96a66cSDavid du Colombier */ 9*5e96a66cSDavid du Colombier #define U8GET(p) ((p)[0]) 10*5e96a66cSDavid du Colombier #define U16GET(p) (((p)[0]<<8)|(p)[1]) 11*5e96a66cSDavid du Colombier #define U32GET(p) (((p)[0]<<24)|((p)[1]<<16)|((p)[2]<<8)|(p)[3]) 12*5e96a66cSDavid du Colombier #define U48GET(p) (((uvlong)U16GET(p)<<32)|(uvlong)U32GET((p)+2)) 13*5e96a66cSDavid du Colombier #define U64GET(p) (((uvlong)U32GET(p)<<32)|(uvlong)U32GET((p)+4)) 14*5e96a66cSDavid du Colombier 15*5e96a66cSDavid du Colombier #define U8PUT(p,v) (p)[0]=(v) 16*5e96a66cSDavid du Colombier #define U16PUT(p,v) (p)[0]=(v)>>8;(p)[1]=(v) 17*5e96a66cSDavid du Colombier #define U32PUT(p,v) (p)[0]=(v)>>24;(p)[1]=(v)>>16;(p)[2]=(v)>>8;(p)[3]=(v) 18*5e96a66cSDavid du Colombier #define U48PUT(p,v,t32) t32=(v)>>32;U16PUT(p,t32);t32=(v);U32PUT((p)+2,t32) 19*5e96a66cSDavid du Colombier #define U64PUT(p,v,t32) t32=(v)>>32;U32PUT(p,t32);t32=(v);U32PUT((p)+4,t32) 20*5e96a66cSDavid du Colombier 21*5e96a66cSDavid du Colombier void 22*5e96a66cSDavid du Colombier headerPack(Header *h, uchar *p) 23*5e96a66cSDavid du Colombier { 24*5e96a66cSDavid du Colombier memset(p, 0, HeaderSize); 25*5e96a66cSDavid du Colombier U32PUT(p, HeaderMagic); 26*5e96a66cSDavid du Colombier U16PUT(p+4, HeaderVersion); 27*5e96a66cSDavid du Colombier U16PUT(p+6, h->blockSize); 28*5e96a66cSDavid du Colombier U32PUT(p+8, h->super); 29*5e96a66cSDavid du Colombier U32PUT(p+12, h->label); 30*5e96a66cSDavid du Colombier U32PUT(p+16, h->data); 31*5e96a66cSDavid du Colombier U32PUT(p+20, h->end); 32*5e96a66cSDavid du Colombier } 33*5e96a66cSDavid du Colombier 34*5e96a66cSDavid du Colombier int 35*5e96a66cSDavid du Colombier headerUnpack(Header *h, uchar *p) 36*5e96a66cSDavid du Colombier { 37*5e96a66cSDavid du Colombier if(U32GET(p) != HeaderMagic){ 38*5e96a66cSDavid du Colombier vtSetError("vac header bad magic"); 39*5e96a66cSDavid du Colombier return 0; 40*5e96a66cSDavid du Colombier } 41*5e96a66cSDavid du Colombier h->version = U16GET(p+4); 42*5e96a66cSDavid du Colombier if(h->version != HeaderVersion){ 43*5e96a66cSDavid du Colombier vtSetError("vac header bad version"); 44*5e96a66cSDavid du Colombier return 0; 45*5e96a66cSDavid du Colombier } 46*5e96a66cSDavid du Colombier h->blockSize = U16GET(p+6); 47*5e96a66cSDavid du Colombier h->super = U32GET(p+8); 48*5e96a66cSDavid du Colombier h->label = U32GET(p+12); 49*5e96a66cSDavid du Colombier h->data = U32GET(p+16); 50*5e96a66cSDavid du Colombier h->end = U32GET(p+20); 51*5e96a66cSDavid du Colombier return 1; 52*5e96a66cSDavid du Colombier } 53*5e96a66cSDavid du Colombier 54*5e96a66cSDavid du Colombier void 55*5e96a66cSDavid du Colombier labelPack(Label *l, uchar *p, int i) 56*5e96a66cSDavid du Colombier { 57*5e96a66cSDavid du Colombier p += i*LabelSize; 58*5e96a66cSDavid du Colombier U8PUT(p, l->state); 59*5e96a66cSDavid du Colombier U8PUT(p+1, l->type); 60*5e96a66cSDavid du Colombier U32PUT(p+2, l->epoch); 61*5e96a66cSDavid du Colombier U32PUT(p+6, l->epochClose); 62*5e96a66cSDavid du Colombier U32PUT(p+10, l->tag); 63*5e96a66cSDavid du Colombier } 64*5e96a66cSDavid du Colombier 65*5e96a66cSDavid du Colombier int 66*5e96a66cSDavid du Colombier labelUnpack(Label *l, uchar *p, int i) 67*5e96a66cSDavid du Colombier { 68*5e96a66cSDavid du Colombier p += i*LabelSize; 69*5e96a66cSDavid du Colombier l->state = p[0]; 70*5e96a66cSDavid du Colombier l->type = p[1]; 71*5e96a66cSDavid du Colombier l->epoch = U32GET(p+2); 72*5e96a66cSDavid du Colombier l->epochClose = U32GET(p+6); 73*5e96a66cSDavid du Colombier l->tag = U32GET(p+10); 74*5e96a66cSDavid du Colombier 75*5e96a66cSDavid du Colombier if(l->type > BtMax){ 76*5e96a66cSDavid du Colombier Bad: 77*5e96a66cSDavid du Colombier vtSetError(EBadLabel); 78*5e96a66cSDavid du Colombier fprint(2, "labelUnpack %.2ux %.2ux %.8ux %.8ux %.8ux\n", 79*5e96a66cSDavid du Colombier l->state, l->type, l->epoch, l->epochClose, l->tag); 80*5e96a66cSDavid du Colombier return 0; 81*5e96a66cSDavid du Colombier } 82*5e96a66cSDavid du Colombier if(l->state != BsBad && l->state != BsFree){ 83*5e96a66cSDavid du Colombier if(!(l->state&BsAlloc)) 84*5e96a66cSDavid du Colombier goto Bad; 85*5e96a66cSDavid du Colombier if(l->state&~BsMask) 86*5e96a66cSDavid du Colombier goto Bad; 87*5e96a66cSDavid du Colombier if(l->state&BsClosed){ 88*5e96a66cSDavid du Colombier if(l->epochClose == ~(u32int)0) 89*5e96a66cSDavid du Colombier goto Bad; 90*5e96a66cSDavid du Colombier }else{ 91*5e96a66cSDavid du Colombier if(l->epochClose != ~(u32int)0) 92*5e96a66cSDavid du Colombier goto Bad; 93*5e96a66cSDavid du Colombier } 94*5e96a66cSDavid du Colombier } 95*5e96a66cSDavid du Colombier return 1; 96*5e96a66cSDavid du Colombier } 97*5e96a66cSDavid du Colombier 98*5e96a66cSDavid du Colombier u32int 99*5e96a66cSDavid du Colombier globalToLocal(uchar score[VtScoreSize]) 100*5e96a66cSDavid du Colombier { 101*5e96a66cSDavid du Colombier int i; 102*5e96a66cSDavid du Colombier 103*5e96a66cSDavid du Colombier for(i=0; i<VtScoreSize-4; i++) 104*5e96a66cSDavid du Colombier if(score[i] != 0) 105*5e96a66cSDavid du Colombier return NilBlock; 106*5e96a66cSDavid du Colombier 107*5e96a66cSDavid du Colombier return U32GET(score+VtScoreSize-4); 108*5e96a66cSDavid du Colombier } 109*5e96a66cSDavid du Colombier 110*5e96a66cSDavid du Colombier void 111*5e96a66cSDavid du Colombier localToGlobal(u32int addr, uchar score[VtScoreSize]) 112*5e96a66cSDavid du Colombier { 113*5e96a66cSDavid du Colombier memset(score, 0, VtScoreSize-4); 114*5e96a66cSDavid du Colombier U32PUT(score+VtScoreSize-4, addr); 115*5e96a66cSDavid du Colombier } 116*5e96a66cSDavid du Colombier 117*5e96a66cSDavid du Colombier void 118*5e96a66cSDavid du Colombier entryPack(Entry *e, uchar *p, int index) 119*5e96a66cSDavid du Colombier { 120*5e96a66cSDavid du Colombier ulong t32; 121*5e96a66cSDavid du Colombier int flags; 122*5e96a66cSDavid du Colombier 123*5e96a66cSDavid du Colombier p += index * VtEntrySize; 124*5e96a66cSDavid du Colombier 125*5e96a66cSDavid du Colombier U32PUT(p, e->gen); 126*5e96a66cSDavid du Colombier U16PUT(p+4, e->psize); 127*5e96a66cSDavid du Colombier U16PUT(p+6, e->dsize); 128*5e96a66cSDavid du Colombier flags = e->flags | ((e->depth << VtEntryDepthShift) & VtEntryDepthMask); 129*5e96a66cSDavid du Colombier U8PUT(p+8, flags); 130*5e96a66cSDavid du Colombier memset(p+9, 0, 5); 131*5e96a66cSDavid du Colombier U48PUT(p+14, e->size, t32); 132*5e96a66cSDavid du Colombier 133*5e96a66cSDavid du Colombier if(flags & VtEntryLocal){ 134*5e96a66cSDavid du Colombier if(globalToLocal(e->score) == NilBlock) 135*5e96a66cSDavid du Colombier abort(); 136*5e96a66cSDavid du Colombier memset(p+20, 0, 7); 137*5e96a66cSDavid du Colombier U8PUT(p+27, e->archive); 138*5e96a66cSDavid du Colombier U32PUT(p+28, e->snap); 139*5e96a66cSDavid du Colombier U32PUT(p+32, e->tag); 140*5e96a66cSDavid du Colombier memmove(p+36, e->score+16, 4); 141*5e96a66cSDavid du Colombier }else 142*5e96a66cSDavid du Colombier memmove(p+20, e->score, VtScoreSize); 143*5e96a66cSDavid du Colombier } 144*5e96a66cSDavid du Colombier 145*5e96a66cSDavid du Colombier int 146*5e96a66cSDavid du Colombier entryUnpack(Entry *e, uchar *p, int index) 147*5e96a66cSDavid du Colombier { 148*5e96a66cSDavid du Colombier p += index * VtEntrySize; 149*5e96a66cSDavid du Colombier 150*5e96a66cSDavid du Colombier e->gen = U32GET(p); 151*5e96a66cSDavid du Colombier e->psize = U16GET(p+4); 152*5e96a66cSDavid du Colombier e->dsize = U16GET(p+6); 153*5e96a66cSDavid du Colombier e->flags = U8GET(p+8); 154*5e96a66cSDavid du Colombier e->depth = (e->flags & VtEntryDepthMask) >> VtEntryDepthShift; 155*5e96a66cSDavid du Colombier e->flags &= ~VtEntryDepthMask; 156*5e96a66cSDavid du Colombier e->size = U48GET(p+14); 157*5e96a66cSDavid du Colombier 158*5e96a66cSDavid du Colombier if(e->flags & VtEntryLocal){ 159*5e96a66cSDavid du Colombier e->archive = p[27]; 160*5e96a66cSDavid du Colombier e->snap = U32GET(p+28); 161*5e96a66cSDavid du Colombier e->tag = U32GET(p+32); 162*5e96a66cSDavid du Colombier memset(e->score, 0, 16); 163*5e96a66cSDavid du Colombier memmove(e->score+16, p+36, 4); 164*5e96a66cSDavid du Colombier }else{ 165*5e96a66cSDavid du Colombier e->archive = 0; 166*5e96a66cSDavid du Colombier e->snap = 0; 167*5e96a66cSDavid du Colombier e->tag = 0; 168*5e96a66cSDavid du Colombier memmove(e->score, p+20, VtScoreSize); 169*5e96a66cSDavid du Colombier } 170*5e96a66cSDavid du Colombier 171*5e96a66cSDavid du Colombier return 1; 172*5e96a66cSDavid du Colombier } 173*5e96a66cSDavid du Colombier 174*5e96a66cSDavid du Colombier int 175*5e96a66cSDavid du Colombier entryType(Entry *e) 176*5e96a66cSDavid du Colombier { 177*5e96a66cSDavid du Colombier return (((e->flags & VtEntryDir) != 0) << 3) | e->depth; 178*5e96a66cSDavid du Colombier } 179*5e96a66cSDavid du Colombier 180*5e96a66cSDavid du Colombier 181*5e96a66cSDavid du Colombier void 182*5e96a66cSDavid du Colombier superPack(Super *s, uchar *p) 183*5e96a66cSDavid du Colombier { 184*5e96a66cSDavid du Colombier u32int t32; 185*5e96a66cSDavid du Colombier 186*5e96a66cSDavid du Colombier memset(p, 0, SuperSize); 187*5e96a66cSDavid du Colombier U32PUT(p, SuperMagic); 188*5e96a66cSDavid du Colombier assert(s->version == SuperVersion); 189*5e96a66cSDavid du Colombier U16PUT(p+4, s->version); 190*5e96a66cSDavid du Colombier U32PUT(p+6, s->epochLow); 191*5e96a66cSDavid du Colombier U32PUT(p+10, s->epochHigh); 192*5e96a66cSDavid du Colombier U64PUT(p+14, s->qid, t32); 193*5e96a66cSDavid du Colombier U32PUT(p+22, s->active); 194*5e96a66cSDavid du Colombier U32PUT(p+26, s->next); 195*5e96a66cSDavid du Colombier U32PUT(p+30, s->current); 196*5e96a66cSDavid du Colombier memmove(p+34, s->last, VtScoreSize); 197*5e96a66cSDavid du Colombier memmove(p+54, s->name, sizeof(s->name)); 198*5e96a66cSDavid du Colombier } 199*5e96a66cSDavid du Colombier 200*5e96a66cSDavid du Colombier int 201*5e96a66cSDavid du Colombier superUnpack(Super *s, uchar *p) 202*5e96a66cSDavid du Colombier { 203*5e96a66cSDavid du Colombier memset(s, 0, sizeof(*s)); 204*5e96a66cSDavid du Colombier if(U32GET(p) != SuperMagic) 205*5e96a66cSDavid du Colombier goto Err; 206*5e96a66cSDavid du Colombier s->version = U16GET(p+4); 207*5e96a66cSDavid du Colombier if(s->version != SuperVersion) 208*5e96a66cSDavid du Colombier goto Err; 209*5e96a66cSDavid du Colombier s->epochLow = U32GET(p+6); 210*5e96a66cSDavid du Colombier s->epochHigh = U32GET(p+10); 211*5e96a66cSDavid du Colombier s->qid = U64GET(p+14); 212*5e96a66cSDavid du Colombier if(s->epochLow == 0 || s->epochLow > s->epochHigh || s->qid == 0) 213*5e96a66cSDavid du Colombier goto Err; 214*5e96a66cSDavid du Colombier s->active = U32GET(p+22); 215*5e96a66cSDavid du Colombier s->next = U32GET(p+26); 216*5e96a66cSDavid du Colombier s->current = U32GET(p+30); 217*5e96a66cSDavid du Colombier memmove(s->last, p+34, VtScoreSize); 218*5e96a66cSDavid du Colombier memmove(s->name, p+54, sizeof(s->name)); 219*5e96a66cSDavid du Colombier s->name[sizeof(s->name)-1] = 0; 220*5e96a66cSDavid du Colombier return 1; 221*5e96a66cSDavid du Colombier Err: 222*5e96a66cSDavid du Colombier memset(s, 0, sizeof(*s)); 223*5e96a66cSDavid du Colombier vtSetError(EBadSuper); 224*5e96a66cSDavid du Colombier return 0; 225*5e96a66cSDavid du Colombier } 226*5e96a66cSDavid du Colombier 227