1 #include <u.h> 2 #include <libc.h> 3 #include <venti.h> 4 #include "cvt.h" 5 6 static int 7 checksize(int n) 8 { 9 if(n < 256 || n > VtMaxLumpSize) { 10 werrstr("bad block size %#ux", n); 11 return -1; 12 } 13 return 0; 14 } 15 16 void 17 vtentrypack(VtEntry *e, uchar *p, int index) 18 { 19 ulong t32; 20 int flags; 21 uchar *op; 22 int depth; 23 24 p += index * VtEntrySize; 25 op = p; 26 27 U32PUT(p, e->gen); 28 p += 4; 29 U16PUT(p, e->psize); 30 p += 2; 31 U16PUT(p, e->dsize); 32 p += 2; 33 depth = e->type&VtTypeDepthMask; 34 flags = (e->flags&~(_VtEntryDir|_VtEntryDepthMask)); 35 flags |= depth << _VtEntryDepthShift; 36 if(e->type - depth == VtDirType) 37 flags |= _VtEntryDir; 38 U8PUT(p, flags); 39 p++; 40 memset(p, 0, 5); 41 p += 5; 42 U48PUT(p, e->size, t32); 43 p += 6; 44 memmove(p, e->score, VtScoreSize); 45 p += VtScoreSize; 46 47 assert(p-op == VtEntrySize); 48 } 49 50 int 51 vtentryunpack(VtEntry *e, uchar *p, int index) 52 { 53 uchar *op; 54 55 p += index * VtEntrySize; 56 op = p; 57 58 e->gen = U32GET(p); 59 p += 4; 60 e->psize = U16GET(p); 61 p += 2; 62 e->dsize = U16GET(p); 63 p += 2; 64 e->flags = U8GET(p); 65 e->type = (e->flags&_VtEntryDir) ? VtDirType : VtDataType; 66 e->type += (e->flags & _VtEntryDepthMask) >> _VtEntryDepthShift; 67 e->flags &= ~(_VtEntryDir|_VtEntryDepthMask); 68 p++; 69 p += 5; 70 e->size = U48GET(p); 71 p += 6; 72 memmove(e->score, p, VtScoreSize); 73 p += VtScoreSize; 74 75 assert(p-op == VtEntrySize); 76 77 if(!(e->flags & VtEntryActive)) 78 return 0; 79 80 /* 81 * Some old vac files use psize==0 and dsize==0 when the 82 * file itself has size 0 or is zeros. Just to make programs not 83 * have to figure out what block sizes of 0 means, rewrite them. 84 */ 85 if(e->psize == 0 && e->dsize == 0 86 && memcmp(e->score, vtzeroscore, VtScoreSize) == 0){ 87 e->psize = 4096; 88 e->dsize = 4096; 89 } 90 if(checksize(e->psize) < 0 || checksize(e->dsize) < 0) 91 return -1; 92 93 return 0; 94 } 95 96